Herança

Padrão

Olá leitores! Apesar de meio parada, a nossa série de posts sobre Orientação a Objetos continua! Hoje iremos tratar de um assunto de extrema importância dentro das técnicas de modelagem de sistemas orientados a objetos: os conceitos de Herança (ou Inheritance). Mas o que vem a ser herança?

A grosso modo, podemos dizer que programar utilizando herança é reaproveitar código que será comum a outras classes. Utilizar herança é descobrir semelhanças entre classes.

Herança lembra família… é o que é transmitido de uma geração para outra…

Projetar utilizando herança significa colocar código comum em uma classe e dizer às classes mais específicas que a classe comum (mais abstrata) é sua superclasse. Quando uma classe herda de outra, a subclasse herda da superclasse. A notação de herança em C++ é…

class SubClasse: public SuperClasse {<br />
...<br />
};

… e em Java…

class SubClasse extends SuperClasse {<br />
...<br />
}

Voltando aos conceitos, dizemos que um relacionamento de herança significa que a subclasse herdará os membros da superclasse. Os “membros de uma classe” são os seus métodos e suas variáveis de instância (ou atributos). Vamos a um exemplo prático. Temos uma classe chamada Médico que iremos especializar em Clínico Geral e Cirurgião. Na notação UML (Unified Modeling Language), teríamos algo assim:

Esta é a notação de herança na UML. A classe mãe (ou superclasse) ligada a suas filhas (subclasses) por uma linha, com um triângulo indicando a presença de herança. Bom, neste caso, temos a classe mais abstrata, chamada Médico que possui uma variável de instância chamada trabalhaNoHospital e um método chamado tratarPaciente(). As duas subclasses, Clínico Geral e Cirurgião, automaticamente possuem estes atributos em seu escopo. No caso do Clínico Geral, ele possui, adicionalmente, uma variável de instância chamada atendeEmCasa e um método receitar(), que são específicos dele. Já a classe Cirurgião sobrescreve o método tratarPaciente() e adiciona o método fazerIncisão().

Mas espere aí? O que significa sobrescrever um método?

No nosso exemplo, a superclasse Médico tem o seu método tratarPaciente(), pois é uma ação comum a todo médico. No caso da superclasse, todo médico faz um check-up em seu paciente. Esse é o comportamento comum. A classe Clínico Geral possui esse comportamento, ou seja, um médico clínico geral, ao tratar o paciente, realiza um check-up nele. Já no caso da classe Cirurgião, ele também trata o paciente. Porém, o seu tratamento consiste em realizar a cirurgia no tratamento. Apesar de ter o mesmo método, o seu comportamento é diferente da classe mãe. Assim, ela sobrescreve o método da superclasse, adicionando seu comportamento próprio.

Vamos ver, então, como ficaria isso nas linguagens C++…

class Medico<br />
{<br />
    bool trabalhaNoHospital;</p>
<p>    void tratarPaciente()<br />
    {<br />
        // faz um check-up<br />
    }<br />
};

class ClinicoGeral: public Medico<br />
{<br />
    bool atendeEmCasa;</p>
<p>    void receitar()<br />
    {<br />
        // para tratar problemas simples<br />
    }<br />
};

class Cirurgiao: public Medico<br />
{<br />
    void tratarPaciente()<br />
    {<br />
        // realizar cirurgia<br />
    }</p>
<p>    void fazerIncisao()<br />
    {<br />
        // faz a incisão (corta o paciente!)<br />
    }<br />
};

… e Java…

public class Medico {</p>
<p>    boolean trabalhaNoHospital;</p>
<p>    void tratarPaciente() {<br />
        // faz um check-up<br />
    }<br />
}

public class ClinicoGeral extends Medico {</p>
<p>    boolean atendeEmCasa;</p>
<p>    void receitar() {<br />
        // para tratar problemas simples<br />
    }<br />
}

public class Cirurgiao extends Medico {</p>
<p>    void tratarPaciente() {<br />
        // realizar cirurgia<br />
    }</p>
<p>    void fazerIncisao() {<br />
        // faz a incisão (corta o paciente!)<br />
    }<br />
}

Como podem perceber, a sintaxe para a realização de herança nas linguagens é bastante simples, tanto em C++, quanto em Java.

Para não estender muito o post e evitar deixá-lo demasiadamente complexo, vamos encerrando por aqui. Recomendo que, para um melhor aprendizado sobre o assunto, vocês devam procurar material extra, tentar implementar pequenas estruturas de herança, enfim, realmente praticarem. Só através da prática é que conseguirão amadurecer os conceitos e conseguirão englobá-los no desenvolvimento de seus aplicativos.

No próximo post desta série, falaremos sobre o conceito de classes e métodos abstratos, assunto bastante interessante na Orientação a Objetos.

Até lá!