
Apresentação
Introdução
Dando continuação a nossa série, apresentaremos neste artigo o conceito de herança, um dos principais meios utilizados para intra-comunicar duas classes. As heranças entre classes estabelecem um parentesco entre elas, facilitando muito nosso trabalho, principalmente, em projetos de maior porte.
Herança
Conceito
Quando ouvimos sobre herança, a primeira imagem que nos veem na mente é uma árvore genealógica envolvendo antecedentes e descendentes, em que se passa uma sequência de características a cada geração. Bom, na programação orientada a objetos, o princípio é o mesmo. Quando uma classe, chamada classe-filha, ou classe descendente, extende outra classe, isto é, recebe uma herança desta classe, diz-se que criou uma relação de parentesco entre elas. A classe-filha, assim, herda todos os atributos e métodos, de acordo com o encapsulamento definido, da classe que extende, chamada classe-mãe, superclasse, ou classe ancestral.
Sintaxe
E como definimos uma relação de parentesco entre classes e como definiríamos qual delas será a classe-mãe e qual será a classe-filha? Fácil. Para estabeler este parentesco entre duas classes, basta utilizar a estrutura extends ao declarar a classe-filha. Lembrando que a classe-mão já deverá estar devidamente declarada.
# Exemplo 1
Consideremos duas classes: a classe que já está declarada, de nome ParentClass, que será a nossa classe-mãe, e outra, que chamaremos de ChildClass, que iremos declarar como classe-filha da ParentClass.
Para estabelecer tal parentesco, utlizamos o seguinte comando, ao declarar nossa classe-filha:
1 2 3 4 5 | // Declaração da classe-mãe class ParentClass { ... } // Declaração da classe-filha e da relação de parentesco class ChildClass extends ParentClass { ... } |
Perceba que a estrutura extends localiza-se logo após o nome da nossa classe-filha, seguida do nome da nossa classe-mãe. A partir disto, podemos acessar qualquer atributo e método, de acordo com o encapsulamento definido, da nossa classe-mãe na nossa classe-filha.
Acessando atributos e métodos
Para acessar os atributos e métodos herdados na classe-filha da classe-mãe, podemos considerar que tais estruturas foram declaradas dentro da própria classe-filha, podendo ser acessadas pela estrutura $this normalmente.
Importante
Ao se utilizar atributos e métodos na classe-filha com mesmo nome da classe-mãe, estará sobescrevendo-os, perdendo os dados declarados na classe-mãe. Caso seja necessário essa reescrita, podemos utilizar as estruturas self e parent para diferenciar de qual classe cada estrutura pertence. O self para a classe que estamos trabalhando, a classe-filha, e parent para a classe-mãe.
# Exemplo 2
Veja a declaração da nossa classe-mãe:
1 2 3 4 5 6 | class ParentClass { public function write() { echo "webARTz - Onde a WEB encontra a ARTE"; } } |
Agora, a declaração da nossa classe-filha, sem reescrita do método:
1 | class ChildClass extends ParentClass {} |
Ao instanciarmos nossa classe-filha em um objeto, poderemos acessar o método write da classe-mãe normalmente. Veja:
1 2 3 4 5 | // Instanciando a classe no objeto $obj = new ChildClass; // Chamando o método write $obj->write(); |
O resultado será:
1 | webARTz - Onde a WEB encontra a ARTE |
Porém, se declararmos nossa classe-filha com reescrita do método. Por exemplo:
1 2 3 4 5 6 | class ChildClass extends ParentClass { public function write() { echo "Olá mundo"; } } |
O resultado da nossa operação:
1 2 3 4 5 | // Instanciando a classe no objeto $obj = new ChildClass; // Chamando o método write $obj->write(); |
Será:
1 | Olá mundo |
Poderíamos, então, criar um novo método na nossa classe-filha, que referencie o método sobescrito da classe-mãe através da estrutura parent. Veja um exemplo:
1 2 3 4 5 6 7 8 | class ChildClass extends ParentClass { ... public function writeParent() { return parent::write(); } } |
Assim, na operação:
1 2 3 4 5 6 7 8 | // Instanciando a classe no objeto $obj = new ChildClass; // Chamando o método write $obj->write(); // Chamando o nosso novo método writeParent $obj->writeParent(); |
Teremos como resultado:
1 2 | Olá mundo webARTz - Onde a WEB encontra a ARTE |
Perceba que, pelo comando parent::write(), definimos que, ao ser chamado o método writeParent, da classe-filha, seja executado o método write da classe-mãe.
Heranças Múltiplas
Conceito
O conceito de heranças múltiplas é segue o conceito de heranças, com o diferencial de que uma classe-filha herda atributos e métodos de mais de uma classe. Como é possível? Imagine que a nossa classe-mãe também seja uma classe-filha, isto é, herda estruturas de uma outra classe, chamaremos de classe-avó. Quando nossa classe-filha herda as estruturas da classe-mãe, herda também as estruturas da classe-avó.
O uso de heranças múltiplos deve ser moderado e utilizado com extremo cuidado, pois, quando utilizado excessivamente, pode atrabalhar na legibilidade e manutenção do código.
Entendendo o Parentesco
Para exemplificar bem a relação de parentesco, incrementando o conceito de heranças múltiplas, usarei uma série animada que deve ser de conhecimento de todos: The Simpsons. Mostrado devidamente a árvore genealógica da nossa série, simularemos classes para cada personagem e, seguindo esta árvore, criaremos nossas relações de parentesco.
Árvore Genealógica
Veja a árvore genealógica da série The Simpsons:

As Classes
A família Simpsons iniciou no personagem Sven Simpson, logo, este não herdou característica alguma de ninguém. Assim, a classe SvenSimpson será a nossa superclasse, que será extendida por classes, mas não extende alguma classe.
1 | class SvenSimpson { ... } |
Seguindo, temos a personagem Claretta Ethridge, que, ao casar com Sven Simpson, estabeleceu um grau de parentesco. Assim, a classe ClarettaEthridge herdará as características de SvenSimpson.
1 | class ClarettaEthridge extends SvenSimpson { ... } |
Desta relação, nasceram dois filhos: Lambert Simpson e Rupert Simpson. Ambos herdarão características do pai e da mãe. Porém, o PHP não suporta extensões múltiplas em uma classe, mas, sem preocupações. Utilizando o conceito de heranças múltiplas, se a classe LambertSimpson e RupertSimpson herdarem as características de ClarettaEthridge, herdarão também as características de SvenSimpson, pois ClarettaEthridge herda tais características e as repassa às suas classes-filhas. Assim:
1 | class LambertSimpson extends ClarettaEthridge { ... } |
1 | class RupertSimpson extends ClarettaEthridge { ... } |
Seguindo, temos a personagem Winifred Running Goat, casando-se com Rupert Simpson. Então:
1 | class WinifredRunningGoat extends RupertSimpson { ... } |
Desta relação, surgem cinco novos personagens: Trixie Simpson, Prudence Simpson, Galston Simpson, Ivy Simpson e Garwood Simpson. Este último casa-se com Clowra Stillman. Temos, então:
1 | class TrixieSimpson extends WinifredRunningGoat { ... } |
1 | class PrudenceSimpson extends WinifredRunningGoat { ... } |
1 | class GalstonSimpson extends WinifredRunningGoat { ... } |
1 | class IvySimpson extends WinifredRunningGoat { ... } |
1 | class GarwoodSimpson extends WinifredRunningGoat { ... } |
1 | class ClowtaStillman extends GarwoodSimpson { ... } |
Desta última relação, surgem quatro personagens: Floyd Simpson, Pippa Simpson, Zeke Simpson e Howland Simpson.
1 | class FloydSimpson extends ClowtaStillman { ... } |
1 | class PippaSimpson extends ClowtaStillman { ... } |
1 | class ZekeSimpson extends ClowtaStillman { ... } |
1 | class HowlandSimpson extends ClowtaStillman { ... } |
Howland Simpson casa-se com Gabby Crouse, então:
1 | class GabbyCrouse extends HowlandSimpson { ... } |
Desta relação, surgem os personagens: Lou Simpson, Dulcine Simpson, Hugo Simpson, Gaston Simpson e "Old Tut" Simpson.
1 | class LouSimpson extends GabbyCrouse { ... } |
1 | class DulcineSimpson extends GabbyCrouse { ... } |
1 | class HugoSimpson extends GabbyCrouse { ... } |
1 | class GastonSimpson extends GabbyCrouse { ... } |
1 | class OldTutSimpson extends GabbyCrouse { ... } |
O último casa-se com "Happy" Dinsdale, no qual, da relação, surgem quatro novos personagens: Twitta Simpson, Elrita Simpson, Bonita Simpson e Orville Simpson.
1 | class HappyDinsdale extends OldTutSimpson { ... } |
1 | class TwittaSimpson extends HappyDinsdale { ... } |
1 | class ElritaSimpson extends HappyDinsdale { ... } |
1 | class BonitaSimpson extends HappyDinsdale { ... } |
1 | class OrvilleSimpson extends HappyDinsdale { ... } |
Orville Simpson casou-se com Yuma Hickman, gerando Abraham Simpson (vovô):
1 | class YumaHickman extends OrvilleSimpson { ... } |
1 | class AbrahamSimpson extends YumaHicjman { ... } |
Abraham Simpson se relaciona com duas mulheres: Edwina e Mona Olsen.
1 | class Edwina entends AbrahamSimpson { ... } |
1 | class MonaOlsen entends AbrahamSimpson { ... } |
De sua relação com Edwina, surge a personagem Abbie Simpson:
1 | class AbbieSimpson extends Edwina { ... } |
E da relação com Mona Olsen, nasce Homer Simpson:
1 | class HomerSimpson extends MonaOlsen { ... } |
Homer Simpson casa-se com Marge Bolvier:
1 | class MargeBolvier extends HomerSimpson { ... } |
E desta relação, surgem os personagens Bart Simpson, Lisa Simpson e Maggie Simpson.
1 | class BartSimpson entends MargeBolvier { ... } |
1 | class LisaSimpson entends MargeBolvier { ... } |
1 | class MaggieSimpson entends MargeBolvier { ... } |
Perceba que a ideia para gerarmos as relações de parentesco entre classes segue a mesma de uma árvore genealógica. Montar um esquema assim, antes de contruir suas classes ajudará a perceber qual será o grau de parentesco entre cada classe.
Conclusão
Bom, espero que tenha ficado bastante claro o conceito de herança. Sei que ficou extenso o artigo, mas dei preferência a este exemplo, pois, além de explicar bem o conceito, utilizando uma árvore genealógica na forma que conhecemos, mostra o quão complicado fica quando utilizamos heranças excessivamente. Imagine se tivessemos implementado atributos e métodos em cada classe, as nossas classes terminais, que provavelmente seriam as que nós trabalharíamos, BartSimpson, LisaSimpson e MaggieSimpson herdariam os atributos e métodos de 16 outras classes. Se cada classe implementasse 10 estruturas, entre atributos e métodos, teríamos 160 estruturas herdadas, o que tornara nosso trabalho bastante complexo. Além disso, este exemplo nos ajudará quando estudarmos interfaces.



















Grátis: API de CEPs para qualquer Linguagem
CodeIgniter e Zend – Frameworks PHP
PHP: Script para Cálculo de Frete dos Correios (Atualizado)
09. PHP Orientado a Objetos – Conceitos: Polimorfismo



