4.4 Herança

4.4.1 Herança Simples

O conceito de herança é construído sobre a ideia de que algumas classes estão intimamente ligadas a outras classes, e que por conta disso, compartilham características em comum (i.e., atributos, métodos, comportamentos, etc.).

Partindo dessa ideia, podemos estabelecer um relacionamento hierárquico entre classes, em que a classe no topo da árvore é a classe mais genérica (geralmente chamada de classe base, ou classe mãe) e à medida que descemos de nível na hierarquia, temos uma nova classe (classe derivada, ou classe filha), que é uma especialização da classe acima. Por conta disso, geralmente nos referimos à relação que vincula uma classe derivada a sua classe base pela frase "Y é um tipo de X" ou "Y é uma especialização da classe X", sendo X a classe base e Y a classe derivada .

Figura 2 – Árvore hierárquica representando o conceito de herança aplicado a classe veículo.

Fonte: Elaborada pelo autor.

O mecanismo de herança permite que uma classe seja definida a partir de uma outra classe já existente, com isso a definição da classe derivada herda automaticamente atributos, métodos e comportamentos da classe base. Por conta disso, herança é considerada uma técnica poderosa, uma vez que encoraja a reusabilidade durante o desenvolvimento e provê uma grande economia de tempo, sem perda de qualidade no desenvolvimento (pois você não precisa reescrever, testar, depurar e manter o código herdado) .

Para exemplificar, imaginemos que precisamos definir uma classe Estudante, a qual possui atributos como número de matrícula, curso, período, etc, ou seja, coisas que remetem à vida escolar de um estudante. Contudo, é relevante também para quem manipulará os objetos do tipo Estudante, saber qual o nome do estudante, sua data de nascimento, seu RG, etc., ou seja, coisas que remetem à pessoa propriamente dita.

Podemos então utilizar o mecanismo de herança e definir a classe Estudante herdando a classe Pessoa que já definimos em exemplos anteriores, uma vez que um estudante é uma especialização de pessoa, ou seja, um tipo especifico de pessoa e que, portanto, além de possuir suas características especificas (matricula, curso, etc.) também deve possuir características de uma pessoa (nome, data de nascimento, etc.).

Utilizando o mecanismo de herança, a definição da classe Estudante fica bem mais simples do que escrever a classe desde o início, como ilustrado no Exemplo 20:

Exemplo 20:

public class Estudante : Pessoa

{

public int matricula;

public string instituicao;

public string curso;

public string periodo;

public int turma;

public DateTime ingresso;

public DateTime jubilamento;

public void apresentarSe()

{

Console.Write("Olá, meu nome é " + nome);

Console.Write(", tenho " + idade + "anos ");

Console.Write("e atualmente estudo " + curso);

Console.Write(" na " + instituicao);

}

}

Note que entre Estudante e Pessoa há um sinal de dois pontos, o que na definição de uma classe em C# indica que a classe Estudante herda a classe Pessoa.

Feito isto os objetos do tipo Estudante compartilham as características de uma Pessoa, como ilustrado no Exemplo 21:

Exemplo 21:

Estudante fulano = new Estudante();

fulano.nome = "Fulano de Tal";

fulano.matricula = 13101659;

fulano.instituicao = "FATEC-SP";

fulano.curso = "Análise e Desenvolvimento de Sistemas";

fulano.setIdade(20);

fulano.falar();

fulano.apresentarSe();

4.4.2 Herança múltipla

Algumas linguagens orientadas a objetos como C++, Scala e Python também oferecem o mecanismo de herança múltipla, que permite que uma classe herde de mais de uma classe ao mesmo tempo.

Figura 3 – Representação do conceito de herança múltipla aplicado a classe CarroAnfibio.

Fonte: Elaborada pelo autor.

Contudo herança múltipla tem sido uma questão sensível por muitos anos, pois pode aumentar a complexidade na programação e gerar ambiguidade em situações onde mais de uma classe base possui atributos ou métodos como mesmo nome, embora hoje já haja abordagens que resolvem essa ambigüidade (i.e., em C++ por exemplo, é usado classePai::AtributoAmbiguo para explicitar de qual classe o atributo ambíguo será acessado). Ilustração no Exemplo 22 da implementação de herança múltipla em C++.

Exemplo 22:

class Estudante

{

public:

void apresentarSe() { ... }

protected:

int idade;

string nome;

};

class Trabalhador

{

public:

void trabalhar() { ... }

protected:

double salario;

string nome;

};

class Estagiario : public Estudante, public Trabalhador

{

...

};