Curso de PHP Orientado a Objetos – Parte 6
Sexto artigo do curso de PHP Orientado a Objetos. Neste artigo você aprenderá o conceito de encapsulamento, além de aplicar a visibilidade de métodos e propriedades.
- Entender o significado do encapsulamento para a POO;
- Entender e aplicar a visibilidade dos métodos e propriedades.
- private: Este modificador não permite ser acessado por classes descendentes (classes-filhas), só pode ser acessado dentro da própria classe.
- public: Este modificador é o default (padrão), ou seja, quando um método não tiver um modificador de visibilidade definido, ele sempre será public. Public significa que o método ou propriedade em questão pode ser acessado por todas as outras classes e métodos sem quaisquer restrições.
- protected: Pode ser acessado apenas por métodos da própria classe e classes filhas.
Private
1 2 3 4 5 6 7 |
class Fornecedor{ private $Id; //identificação public $Nome; //nome do produto private $Compra; //valor de compra public $Valor; //valor de venda } |
![]() |
Eclipse exibindo apenas as propriedades públicas da classe Fornecedor |
Criamos o objeto Fornecedor e ao definir as propriedades, o próprio Eclipse, através de sua função autocomplete, carregará somente as funções públicas (public). Perceba que ele não exibe na lista as funções privadas (private).
Se mesmo assim você tentar algo como:
1 2 |
$empresa1 = new Fornecedor(); $empresa1->Compra = 400; |
Será retornado uma mensagem de erro, pois a propriedade Compra é privada (private).
Ok, mas como faço para atribuir algo a essa propriedade caso necessário?
Se você fez essa pergunta, parabéns!
Para atribuir algo, basta criar um método pertencente a classe Fornecedor que manipule estas propriedades. Que tal chamarmos de “Set” para definir e “Get” para obter o conteúdo dos atributos?
Veja o exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class Fornecedor{ private $Id; //identificação public $Nome; //nome do produto private $Compra; //valor de compra public $Valor; //valor de venda /* Olha o método setCompra() * que vai definir um valor para * a propriedade $Compra */ public function setCompra($Compra){ if (is_numeric($Compra) && $compra > 0) { $this->Compra = $Compra; } } /* Vamos agora criar o método * getCompra que vai retornar * o conteúdo da propriedade $compra */ public function getCompra(){ return $this->Compra; } } |
Agora que criamos o método get e set para a propriedade $Compra, é possível realizar a chamada normalmente:
1 2 3 4 |
$empresa1 = new Fornecedor(); $empresa1->Nome = "Vale"; $empresa1->setCompra(400); echo "O valor do produto ".$empresa1->Nome." é de ".$empresa1->getCompra(); |
O interessante neste caso, é perceber que para um determinado valor chegar a propriedade $Compra, ele deve passar pelo método setCompra. Isso nos traz um controle maior sobre a aplicação visto que, você pode realizar várias operações antes da chagada do valor, neste caso perceba que no método setCompra, checamos se o valor é um número (is_numeric) e se é maior que zero.
Poderíamos criar um set e um get para mais elementos definidos como private mas cuidado, utilize os Getters e Setters somente quando existe a real necessidade, variáveis internas ou que não precisam de nenhum tipo de verificação ou tratamento, não utilize.
Prefira sempre utilizar métodos Getter e Setters ao invés de um campo público (public) mas lembre-se, simplificar é a alma da POO, criar dezenas de métodos não simplifica.
Protected
Vimos no exemplo anterior, o uso do parâmetro de visibilidade private. Vale ressaltar que quando uma propriedade é definida como private, ela não pode ser sobrescrita por classes filhas, ou seja, uma classe filha não consegue chamar os métodos setters e getters da classe pai (no caso do atributo estar como private).
Caso você tenha uma classe Funcionário com o método setSalario e o atributo Salário do tipo private, e crie a subclasse Estagiário, você não consegue chamar o método mesmo fazendo uso da herança, está é uma característica do private.
Em outras palavras, se um atributo é do tipo private, ele só funciona na classe que foi declarado, caso você queira fazer uso do mesmo em outras classes (filhas) é necessário modificar o tipo para Protected.
Veja:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Funcionario{ private $Id; private $Nome; private $Nascimento; private $Salario; function setSalario($Salario){ if (is_numeric($Salario) && $Salario > 0) { $this->Salario = $Salario; } } function getSalario(){ return $this->Salario; } } |
Agora, vamos criar a classe Estagiário, que será uma subclasse de Funcionário.
1 2 3 4 5 6 7 8 9 10 11 12 |
class Estagiario extends Funcionario { /* Método getSalario será * sobrescrito pois o estagiário * neste modelo possui um bônus * de 10% */ function getSalario(){ return $this->Salario * 1.10; } } |
Depois das duas classes criadas, vamos criar o objeto estagiário:
1 2 3 |
$junior = new Estagiario; $junior->setSalario(300); echo "O salario é: ".$junior->getSalario; |
Essa ação resultaria em um erro. Isso ocorre porque a propriedade $Salario é uma propriedade private, o que significa que ela somente pode ser acessada de dentro da classe em que ela foi declarada, neste caso, a classe Funcionário.
Para que as subclasses consigam acessar uma propriedade da classe pai, definimos como protected.
Exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Funcionario{ private $Id; private $Nome; private $Nascimento; protected $Salario; function setSalario($Salario){ if (is_numeric($Salario) && $Salario > 0) { $this->Salario = $Salario; } } function getSalario(){ return $this->Salario; } } |
Agora podemos criar a classe Estagiário da mesma forma que fizemos no exemplo anterior e em seguida criar o objeto:
1 2 3 |
$junior = new Estagiario; $junior->setSalario(300); echo "O salario é: ".$junior->getSalario; |
Com essa pequena modificação, tornamos o atributo $Salario “extensível” a todas as classes que forem criadas a partir da classe Funcionário. Este exemplo não retornaria erro.
Public
Explicar o comportamento do modificador de acesso public é simples, pois é a propriedade padrão do PHP. Basicamente, quando não é definido a visibilidade, ela será pública ou seja, você pode modificar, herdar ou atribuir sem nenhum impedimento, não é necessário os métodos Getters e Setters para propriedades públicas.
Terminamos aqui mais um artigo.
No próximo veremos constantes e propriedades estáticas.
Utilize o espaço de comentários para dúvidas, sugestões e elogios.
Ps.: Venho recebendo alguns comentários que tem servido de estímulo para a continuação desta série. Muito obrigado!
Olá, muito bom o conteúdo do curso, excelente na verdade…
ps. vc utiliza eclipse para programar? como vc ativou para ele interpretar as tags do PHP? vlw….
Sim, utilizo o Eclipse.
Neste caso estava tudo no mesmo arquivo (classe e objeto). Você também pode incluir por meio de require_once(). Salve e teste novamente.
Leandro, o seu material é excelente. Parabéns. Tenho feito algo parecido em meu site. Admiro muito a sua vontade de compartilhar o seu conhecimento. Você poderia escrever sobre a arquitetura de software MVC para PHP. Sua explicação é ótima.
Parabéns. Visite meu site, http://www.codigogm.com.br (em fase de desenvolvimento).
Lá vocês encontrarão materiais sobre DOM HTML, jQuery, SQL, PHP, etc.
Valeu e continue escrevendo.
Ei Guilherme! Muito bacana seu site. Obrigado pelo comentário, estou providenciando algo mais completo. Abraços.
Muito bom cara! vlw mesmo! (y)
Bom dia Leandro,
Neste trecho, que segue abaixo:
$junior = new Estagiario;
$junior->setSalario(300);
echo “O salario é: “.$junior->getSalario;
-> getSalario é um método certo?, entao na sintaxe $junior->getSalario, não deveria conter parenteses por se tratar de um método?
No caso ficaria:
$junior->getSalario();
Obrigado por compartilhar seu conhecimento conosco, estou iniciando nos estudos de PHPOO, e to usando seu site como ferramenta de estudo, muito obrigado
Ops, desculpa minha desatenção, eu estava fazendo junto acabei nem lendo o resto.
Gosto muito do vosso tutorial sobe a orientação de objectos, foi o melhor que encontrei para aprender. Continuem assim
Muito bons os seus artigos meu caro. Simples e eficaz. Continue sempre com este trabalho de divulgação do conhecimento, parabéns!
Seu material é ótimo! Na verdade, o melhor que encontrei até agora em português.
Bastante didático e objetivo. Parabéns pela iniciativa e qualidade.
Muito bom suas explicações sobre POO PHP, havia muitas dúvidas sobre Polimorfismo, Herança e Encapsulamento e foi aqui consegui clarear minhas idéias.
Muito bom o conteúdo cara você deveria continuar criando mais aulas, por exemplo de como usar o php POO na pratica seria bom. Vlw brother!
Meu amigo, meus parabéns por este curso. Realmente excelente.