quarta-feira, 21 de março de 2012

Curso de PHP Orientado a Objetos - Parte 3

Esta é a terceira parte do Curso de Php Orientado a Objetos.
Clique aqui para conhecer as partes anteriores.


Ao final deste artigo, você será capaz de:
  • Entender e aplicar o conceito de herança
Herança

Assim como no mundo real, a palavra se refere ao conceito de receber algo, herança aqui pode ser entendida como um mecanismo que permite construir uma nova classe com base em uma classe previamente existente, em que a nova herda automaticamente todos os atributos, comportamentos e implementações da classe-pai. 
Quando se trata de herança, estamos falando de um dos maiores benefícios da Orientação a Objetos, além da capacidade de encapsulamento (essa veremos a seguir, por enquanto, trate o encapsulamento como algo importante). Com a herança, podemos reutilizar partes de código já definidas, além da agilidade, ela elimina a necessidade de duplicar ou rescrever certo código. Essas características nos permitem ao invés de escrevermos uma estrutura totalmente nova, reaproveitar a estrutura existente mesmo que a mesma nos forneça apenas uma base abstrata para o desenvolvimento.

Para estender uma nova classe (chamaremos de subclasse), utilizamos a palavra reservada extends. 
Quando criamos uma subclasse, todos os métodos pertencentes a classe pai podem ser executados. Também é possível sobrescrever os seus métodos e propriedades, a fim de criar novos, com outras características. Se na subclasse é escrito um método com o mesmo nome do método existente na classe pai, passa a vigorar o método da classe filha (subclasse).

Para acessar os métodos sobrescritos ou membros estáticos da classe pai, utilizamos a palavra reservada parent.

É importante destacar que somente os métodos protect e public podem ser reescritos (veremos detalhes sobre isso mais a frente).

Nada melhor que um exemplo para facilitar o entendimento por isso, vamos retornar a nossa classe pessoa e a partir dela criaremos a classe funcionário, pois o funcionário é uma pessoa, consequentemente, funcionário herdará as características da classe pessoa, ao invés de duplicarmos tudo de novo na classe funcionário.

class Pessoa{

  public $Nome;
  public $AnoDeNascimento;
  public $Endereco;
  public $Telefone;

  /* Método Construtor
  *  Inicializa as propriedades
  */

  function __construct($Nome, $AnoDeNascimento, $Endereco, $Telefone){

    $this->Nome = $Nome;
    $this->AnoDeNascimento = $AnoDeNascimento;
    $this->Endereco = $Endereco;
    $this->Telefone = $Telefone;

  }

  /* Método EscreveDados()
  *  Retorna os dados da Pessoa
  */

  function EscreveDados(){

    echo "Nome:  {$this->Nome} 
          Ano de nascimento:  {$this->AnoDeNascimento} 
          Endereço: {$this->Endereco} 
          Telefone: {$this->Telefone}";
  }

  /* Método ObterIdade()
  *  Retorna a idade
  */

  function ObterIdade(){

    $ano_atual = date("Y",time());
    return $ano_atual - $this->AnoDeNascimento;

  }
}


Caso você tenha dúvidas quanto a esta classe, consulte as aulas anteriores.

Agora vamos criar a classe Funcionário, que irá herdar da classe Pessoa, fique atendo aos comentários e não se preocupe caso não entenda alguma parte do código, iremos explicar detalhadamente em seguida:

require_once("Pessoa.class.php");

class Funcionario extends Pessoa{

  public $Salario;
  public $Cargo;
  public $DiaPagamento;

  /* Método Construtor
  *  Inicializa as propriedades
  */

  function __construct($Nome, $AnoDeNascimento, $Endereco, $Telefone, $Salario, $Cargo, $DiaPagamento){

    // Chamada do método do construtor da classe-pai
    parent::__construct($Nome, $AnoDeNascimento, $Endereco, $Telefone);

    // Inicializa as variáveis/propriedades locais da Classe

    $this->Salario = $Salario;
    $this->Cargo = $Cargo;
    $this->DiaPagamento = $DiaPagamento;

  }

  /* Método EscreverSalario
  *  Escreve o salário do funcionário
  */

  function EscreverSalario(){

    echo "Salário: {$this->$Salario} 

    ";

  }

  /* Método EscreveDados()
  *  Este método sobrescreve o método EscreveDados() da classe-pai
  */

  function EscreveDados(){

    parent::EscreveDados();

    echo "Salário: {$this->Salario} 

          Cargo: {$this->Cargo} 

          Dia de pagamento: {$this->DiaPagamento} ";
  }

}

Testando nosso exemplo de herança:


 require_once("Funcionario.class.php");

  $leandro = new Funcionario("Leandro Castro", 1985, "Rua das Flores 33 - Juiz de fora","(32) 3232-3535", 4.000, "Desenvolvedor Java/PHP", 8);

  echo $leandro->ObterIdade();

  $leandro->EscreveDados();

Para um melhor entendimento, você deve colocar em prática os exemplos, analisar e estuda-los.

Vamos começar analisando a classe Funcionário:

require_once("Pessoa.class.php");

Nesta linha estamos adicionando a classe pessoa ao documento, levando em consideração que a classe pessoa está em outro arquivo.

class Funcionario extends Pessoa{

Nesta linha estamos dizendo que a classe Funcionário herdará todas as características de Pessoa. Desta forma, Pessoa será a superclasse, enquanto Funcionário, a subclasse de Pessoa.

  public $Salario;
  public $Cargo;
  public $DiaPagamento;

Nesta parte declaramos as propriedades do Funcionário. Mas funcionário não teria que ter um nome? Deixamos de criar a propriedade nome pois ela já está criada na classe Pessoa, consequentemente a classe Funcionário herdou essa propriedade, sendo assim, não é necessário cria-la novamente.
Continuando:
 function __construct($Nome, $AnoDeNascimento, $Endereco, $Telefone, $Salario, $Cargo, $DiaPagamento){

    // Chamada do método do construtor da classe-pai
    parent::__construct($Nome, $AnoDeNascimento, $Endereco, $Telefone);

Se você achou esta parte complicada, fique tranquilo, é mais simples do que parece.
Lembra que estamos trabalhando na classe Funcionário, que é uma subclasse de Pessoa, com isso, Funcionário possui todos os métodos de Pessoa. Vimos que o construtor também é um método, executado quando criamos o objeto e neste caso, estamos sobrescrevendo este construtor.
A linha 4 retrata exatamente isso, estamos dizendo que o pai (parent::) que irá receber os dados (nome, anodenascimento, endereco e telefone) e a classe Funcionário que ficará responsável pelos demais dados (salario, cargo e diadepagamento).
Se não declarássemos o método construtor na classe Funcionário, seria usado o da classe pai, ou seja, o método construtor de Pessoa.
  function EscreverSalario(){

    echo "Salário: {$this->$Salario} 

    ";

  }
Se você esta estudando com atenção, percebeu que este método foi uma nova implementação, ele não exsite na classe pai, pois além de herdar, você pode criar novos métodos e propriedades.

function EscreveDados(){

    parent::EscreveDados();

    echo "Salário: {$this->Salario} 

          Cargo: {$this->Cargo} 

          Dia de pagamento: {$this->DiaPagamento} ";
  }

Esta parte também é importante, perceba que o método EscreveDados existe na classe pai (volte e verifique) mas foi sobrescrito, e acrescentamos a impressão dos campos de salário, cargo e diadepagamento. Neste caso, será impresso todos os atributos contidos na classe pai (parent::) no método EscreveDados, e também os atributos do método EscreveDados da classe filha, ou seja, um complemento do método pai.

Vale lembrar que o PHP não suporta herança múltipla, isso pode ser feito com o uso de interfaces (veremos no futuro).

Conclusão:
Com este recurso, expandimos nosso código, sem reescreve-lo, isso é extremamente comum quando se trata de criar novas funcionalidades em um software.
Cabe a você estudar e aplicar os conceitos que aprendeu aqui.
Utilize o espaço de comentários para tirar suas dúvidas.
No próximo artigo, veremos o polimorfismo (de forma descomplicada).
Até la!

Um comentário:

  1. ótimos tutoriais! Parabéns pela iniciativa meu amigo. Está me ajudando bastante

    ResponderExcluir