Curso POO com PHP: #4 - Herança

Na vida real diversos itens são especializações de outros itens mais genéricos. Pense por exemplo em uma gato domestico, ele é uma especialização de algo mais genérico como um felino, se pensarmos em diversos felinos diferentes como: Leão, Tigre, Onça, etc... todos eles tem suas características únicas, porém todos eles compartilham diversas características que são comuns entre os felinos. O mesmo ocorre com uma Conta Poupança e uma Conta Corrente. Cada uma delas têm suas especificidades, mas tanto uma quanto a outra são Contas Bancárias, e compartilham características comuns entre elas.

Vamos ver um exemplo em formato de código

<?php

class Pessoa {
    protected $nome = "";

    public function __construct($nome)
    {
        $this->nome = $nome;
    }

    public function obterNome()
    {
        return $this->nome;
    }
}

class Aluno extends Pessoa {
    private $ra = "";

    public function obterRA() {
        return $this->ra;
    }

    public function definirRA($ra) {
        $this->ra = $ra;
    }
}

class Professor extends Pessoa {
    private $codigoFuncionario = "";

    public function obterCodigoFuncionario() {
        return $this->codigoFuncionario;
    }

    public function definirCodigoFuncionario($codigoFuncionario) {
        $this->codigoFuncionario = $codigoFuncionario;
    }
}

$aluno = new Aluno("José");
$aluno->definirRA("ABC1234");

echo "O aluno: " . $aluno->obterNome() . " tem RA: " . $aluno->obterRA();

echo PHP_EOL;

$professor = new Professor("Miguel");
$professor->definirCodigoFuncionario("ABC1234");

echo "O professor: " . $professor->obterNome() . " tem Matrícula: " . $professor->obterCodigoFuncionario();

Mais uma vez vamos analisar ponto a ponto o código acima, porém dessa vez eu preciso que você preste muita atenção, muita atenção mesmo, porque é algo que muita gente tem dificuldade de entender num primeiro momento.

  • Primeiro criamos uma classe chamada Pessoa, essa classe é bem genérica, porque se analisamos bem, um Policial é uma pessoal, um estudante é uma Pessoal, um motorista é uma Pessoa, etc... Perceba que nessa classe há uma propriedade $nome que nem é pública nem é privada ela é protegida (protected). Diferente do modificador de acesso private, que permite que apenas membros da própria classe tenham acesso aos elementos privados, propriedades e métodos com visibilidade protected podem ser acessados a partir da própria classe ou de classes que herdem dela.

  • Na sequência criamos uma classe chamada Aluno, e por meio da palavra reservada extends informamos ao PHP que a classe Aluno deve herdar as características da classe Pessoa. A partir desse momento ocorre algo como se forma uma "mesclagem". Tanto as características presentes em Aluno quando as presentes em Pessoas, agora estão disponíveis em Aluno. Uma analogia seria: "Você é filho de sua mãe, logo, herda algumas características dela como: Cor dos olhos, cor da pele, tipo de cabelo, etc...

  • O mesmo ocorre com a classe Professor, ela estende Pessoa, logo, herdará todas as suas características.

Vamos analisar um pouco mais...

Quando criamos um objeto do tipo Professor, nativamente ele tem os métodos públicos "obterCodigoFuncionario" e "definirCodigoFuncionario", porém, como o mesmo estende a classe Pessoa, ele também passa a ter a sua disposição o método "obterNome". Porém perceba que a propriedade $nome, presente na classe Pessoa é protegida, logo, podemos alterar ela em qualquer classe que estenda Pessoa. Vamos ver isso na prática?

<?php

class Pessoa {
    protected $nome = "";

    public function __construct($nome)
    {
        $this->nome = $nome;
    }

    public function obterNome()
    {
        return $this->nome;
    }
}

class Professor extends Pessoa {
    private $codigoFuncionario = "";

    public function obterCodigoFuncionario() {
        return $this->codigoFuncionario;
    }

    public function definirCodigoFuncionario($codigoFuncionario) {
        $this->codigoFuncionario = $codigoFuncionario;
    }

    public function imprimirNome() {
        echo $this->nome;
    }
}

$professor = new Professor("Miguel");
$professor->imprimirNome();

Mas, e se a propriedade $nome fosse privada, o que ocorreria? Não sabe? Testa ai em seu código e me fala o resultado.

Importante: Normalmente, na vida real, a gente não coloca diversas classes no mesmo arquivo. Porém por enquanto não vamos nos preocupar com isso 😎.