Tutorial PHP: Classes – O básico de uma classe
Neste post da série de tutorias de PHP veremos um pouco sobre classes, que é o primeiro passo para começar a entender a Orientação a Objetos. Na realidade entender o funcionamento de uma classe é primordial para trabalhar corretamente com a orientação a objetos.
O que são as classes?
Olhando pelo ponto de vista procedural (não orientado a objetos), uma classe pode ser considerada um contêiner com várias funções (relembre um pouco sobre funções aqui) agrupadas, funções estas que geralmente estão agrupadas de acordo com suas tarefas.
Do ponto de vista da Orientação a Objetos, segundo a wikipedia, podemos dizer que uma classe é uma estrutura que abstrai um conjunto de objetos que tenham características similares, utilizamos também as classes para representar uma entidade do mundo real no ambiente computacional, abaixo vemos dois exemplos de classes:
<?php /** * Classe representando uma entidade do mundo físico * */ class Funcionario { $nome; $telefone; }
<?php /** * Classe representando um conjunto de objetos de características similares */ class DAO { $conexao; public function conecta() { // Conecta ao banco de dados } public function lista() { // Retorna uma listagem do banco de dados } }
<?php /** * Classe representando uma entidade do mundo físico **/ class Funcionario { $nome; $telefone; } /** * Classe representando um conjunto de objetos de características similares */ class DAO { $conexao; public function conecta() { // Conecta ao banco de dados } public function lista() { // Retorna uma listagem do banco de dados } }
OK! Falando da parte não orientada à objetos, podemos dizer que as classes são um agrupamento de funções que trabalham com tarefas similares, assim como declaramos funções para tarefas específicas sem as classes, com elas também podemos fazê-las de forma que funções com características similares fiquem agrupadas sob um contêiner (classe).
Agora partindo para o lado da orientação à objetos, onde teremos um enfoque maior a partir deste post, a classe abstrai, ou seja, representa de forma computacional, determinado item do mundo real que precisa ser representado em nosso sistema, o exemplo acima mostra uma classe chamada “Funcionário”, nela teríamos características e ações de um funcionário que sejam pertinentes a nosso sistema.
Atributos – Características
Uma classe pode ou não possuir Atributos, que representam as características do objeto que está sendo abstraído por ela, por exemplo:
<?php class Carro { $modelo; $marca; $lugares; $portas; }
No exemplo acima vemos que uma classe que representa um carro, pode ter as seguintes características (atributos), o modelo do carro (Gol, Polo, HB20, Fusca, Gallardo etc), a marca (Volkswagen, Hyundai, Lamboghini), quantidade de lugares e quantidade de portas.
Podemos observar que a declaração de um atributo é semelhante a de uma variável, e seus tipos de dados também segue o mesmo princípio.
Métodos = Ações
Além dos atributos, toda classe também, provavelmente, terá métodos, o qual podemos dizer que são as ações que este objeto pode executar. Ainda usando como exemplo o carro, vejamos:
<?php class Carro { $modelo; $marca; $lugares; $portas; function acelerar() { // Código que faria o carro acelerar } function abrirPorta($porta) { // Código que faria o carro abrir a porta } }
No exemplo acima temos dois métodos, ou seja, nosso carro é capaz de realizar duas ações, abrir uma determinada porta (que será informada como parâmetro ) ou acelerar. É possível observar que, assim como nos atributos, a declaração dos métodos é semelhante a declaração de uma função convencional.
Assinatura de Métodos
Cada método possui uma assinatura, que é, trocando em miúdos, uma espécie de formato que deve ser obedecido ao ser chamado.
Podemos notar que o método abrirPorta recebe o número da porta que ele abrirá, esta informação é obrigatória para que ele trabalhe, caso contrário ele não saberá qual porta abrir.
Podemos ver também que o método acelerar não recebe parâmetros.
Há também a possibilidade de informarmos na assinatura do método qual o tipo do parâmetro que aquele método espera receber, vejamos um outro exemplo:
<?php class Boletim { $aluno; $notas = array(); function setAluno($aluno) { $this->aluno = $aluno; } function addNota($nota){ $this->notas[] = $nota; } }
No código acima podemos notar que ambos os métodos da classe Boletim recebem um parâmetro, porém analisando mais a fundo, o que aconteceria se o método setAluno recebesse como valor “-1”?
Nosso boletim receberia uma informação inconsistente, correto? Isso geraria um bug, ou na pior das hipóteses uma parada do sistema.
Mas, e esses $this???
Por enquanto não nos preocupemos com ele!
Voltando ao exemplo, suponhamos que exista uma outra classe aluno, e que o atributo aluno do boletim deva receber uma instância desta classe.
Faria sentido termos algo assim:
... function setAluno(Aluno $aluno) { $this->aluno = $aluno; } ...
O que nós estamos falando para o interpretador do PHP no trecho acima é que ele só deve aceitar a chamada deste método, caso ele receba uma instância da classe Aluno, isso evita que nossa classe receba um valor que não saiba como tratar. E caso seja chamada com outro tipo de dados, que não uma instância, será gerada uma exceção, que pode ser tratada mais facilmente.
Atenção: Esta é uma forma de se fazer isso, porém não recomendada, pois aumenta o acoplamento, iremos falar mais a respeito disso posteriormente.
Instância
No último parágrafo do exemplo anterior vimos esta palavra, uma instância nada mais é do que uma cópia da classe em memória com o seu estado definido.
Quando falamos do estado de uma classe, falamos na realidade do valor que cada atributo da classe tem armazenado no momento.
Por exemplo:
Boletim -> aluno = "João"; Boletim ->notas = array(5,7,3,5);
Este exemplo acima seria um estado da classe.
Boletim -> aluno = "Ana"; Boletim ->notas = array(2,3,9);
Já este exemplo seria outro estado.
Cada um destes estados estaria em uma instância diferente da classe, que está alocada em um espaço diferente da memória.
Para criarmos uma instância de um classe qualquer associamos ela a uma variável utilizando a palavra reservada new, da seguinte forma:
<?php $boletimAna = new Boletim(); $boletimAna->setAluno('Ana'); $boletimAna->notas = array(3,4,9);
Na primeira linha temos a instanciação da classe, que, basicamente, é quando criamos uma cópia dela e a alocamos na memória.
Nas linhas que seguem, mudamos o estado desta classe de duas formas, a primeira chamando o método setAluno e a segunda associando as notas diretamente ao atributo (o que também não é recomendável, e falaremos mais a respeito no próximo post).
A palavra reservada $this
Aqui voltamos a falar de algo que vimos dentro dos métodos addNota e setAluno, o $this->.
Esta palavra é, na realidade, uma pseudo-variável reservada $this, se refere a instância atual da classe, ou seja, ele altera ou acessa o estado da cópia atual da classe.
O Operador ->
Este operador acessa determinada variável ou método de uma instância de classe, no último exemplo é possível notar que a variável $boletimAna usa o operador -> para chamar o método setAluno e também para acessar o atributo notas de nossa instância.
Construtor
Na maioria das vezes precisamos que uma instância de classe já seja criada com seu estado definido, seja para pré configurar algum atributo internamente, seja para ler estas informações de algum lugar.
Nestes casos a classe deve ter um construtor, que, como o nome sugere, constrói a classe já com um estado pronto para uso. A bem da verdade, toda classe possui um construtor implícito que a inicializa da forma mais básica o possível.
O construtor é declarado como um outro método qualquer, porém utilizando-se da palavra reservada __construct, o exemplo abaixo ilustra isso:
<?php class Boletim { $aluno; $notas = array(); function __construct(Aluno $aluno, $notas = null) { $this->aluno = $aluno; $this->notas = $notas; } function setAluno($aluno) { $this->aluno = $aluno; } function addNota($nota) { $this->notas[] = $nota; } }
Observando o exemplo, vemos o construtor recebendo o aluno e as notas e já os atribuindo ao estado da instância, este método é chamado automaticamente ao chamarmos a palavra reservada new, sendo assim nosso exemplo de criação de instância ficaria assim:
<?php $boletimAna = new Boletim('Ana', array(3,4,9));
Além disso notamos em nosso construtor algo novo na assinatura, $notas = null, isso quer dizer que este parâmetro é opcional, ou seja, quando instanciarmos a classe, caso ele não seja informado, receberá o valor null, assim garantimos que nenhum dos parâmetros fique sem uma definição de valores.
Uma das diretrizes da PSR define como boa prática que todos os parâmetros opcionais sejam colocados por último na assinatura do método, ou seja, é bom evitarmos escrever um método da seguinte forma:
<?php function fazAlgumaCoisa($param1 = true, $param2) { ... }
Bom… Em se tratando de classes o assunto se torna um pouco extenso, sendo assim vamos digerir um pouco melhor o conteúdo deste post, e no próximo veremos mais alguns conceitos, já pensando na orientação a objetos.
Em caso de dúvidas referentes ao assunto desta postagem, deixe nos comentários, e se o conteúdo foi útil de alguma forma, compartilhe com os amigos, pode ser útil para algum deles também 😉
Posts da série:
1 – Tutorial PHP: Classes – O básico de uma classe
2 – Tutorial PHP: Classes – Introdução a Orientação à Objetos
Sobre Rodrigo Teixeira Andreotti
Técnico em Informática formado pela ETEC Lauro Gomes Analista de Sistemas Pela universidade Metodista. Impacta Certified Specialist - Linux Programador PHP desde 2007, atuando em diversos projetos de sistemas internos, migrações, desenvolvimento de API's e sites públicos tanto como freelancer quanto com contrato com empresas. Também atuante como administrador Linux, administrando dois servidores próprios com CentOS, além de prestar serviços de administração e manutenção em servidores para algumas empresas.