Classes cujos membros são herdados são chamadas de classes base, e classes que herdam esses membros são chamadas de classes derivadas. Uma classe derivada pode ter apenas uma classe base direta. No entanto, a herança é transitiva. Se ClassC é derivada da ClassB e ClassB é derivada da ClassA, ClassC herda os membros declarados em ClassB e ClassA.
Conceitualmente, uma classe derivada é uma especialização da classe base. Por exemplo, se você tem uma classe base chamada "Veiculo", você pode ter uma classe derivada chamada “Caminhao” e outra classe derivada chamada “Trator”. Um Caminhão é um veículo, assim como um Trator, mas cada classe derivada deve representar diferentes especializações da classe base. Certamente um caminhão possui características diferentes de um trator, o que resultaria em propriedades e métodos diferentes em cada classe. Da mesma maneira é certo que tanto um caminhão como um trator possuem características semelhantes, que podem ser encapsuladas na classe “Veiculo”.
Quando você define uma classe para derivar de outra classe, a classe derivada implicitamente ganha todos os membros da classe base, exceto seus construtores e destrutores. A classe derivada pode assim reutilizar o código na classe base, sem ter de voltar a implementá-lo. Na classe derivada, você pode adicionar mais membros. Desta maneira, a classe derivada estende a funcionalidade da classe base.
Podemos ver exemplos de herança nas classes do próprio .Net Framework, Por exemplo a classe CollectionBase, que contém propriedades e métodos utilizados pela maioria das classes de Collection (coleções). Ela contém propriedades como Capacity e Count e métodos como Clear() e RemoveAt().
Para utilizar a classe base em outra classe (classe derivada) você faz referência à classe base, colocando o símbolo : (dois pontos) após o nome da classe derivada e em seguida coloque o nome da classe base.
Vamos criar alguns exemplos para vermos os conceitos de herança na prática. Abaixo segue um diagrama de classes com as classes que iremos construir:
O código a seguir define uma classe base chamada AluguelItem e duas classes derivadas DVD e Livro, que herdam a classe AluguelItem.
public class AluguelItem
{
string _titulo;
public string Titulo
{
get { return _titulo; }
set { _titulo = value; }
}
public Boolean VerificaEstoque(string titulo)
{
//codigo para verificar um item no estoque
//returna true para demonstração
return true;
}
}
public class DVD : AluguelItem
{
}
public class Livro : AluguelItem
{
}
public class Livro : AluguelItem
{
string _ISBN;
public string ISBN
{
get { return _ISBN; }
set { _ISBN = value; }
}
}
Há muitas ocasiões em que a classe derivada precisa usar uma funcionalidade da classe base, mas também precisa adicionar alguma funcionalidade exclusiva da própria classe derivada. Neste caso, a classe derivada usa a palavras-chave base para chamar um método da classe base. Vamos exemplificar criando um método na classe DVD chamado Alugar(). Dentro dele utilizaremos o método VerificaEstoque contido na classe base, como mostrado no código a seguir.
public class DVD : AluguelItem
{
public Boolean Alugar(string titulo, int idade)
{
if (base.VerificaEstoque(titulo))
{
//Código para realizar o aluguel
//retorna true para demonstração
return true;
}
else
{
return false;
}
}
}
public class Livro : AluguelItem
{
string _ISBN;
public string ISBN
{
get { return _ISBN; }
set { _ISBN = value; }
}
public Boolean VerificaEstoque(string titulo, string autor)
{
//retorna true para demonstração
return true;
}
}
Neste ponto, um cliente pode criar uma instância da classe base AluguelItem como de qualquer uma das classes bases Livro ou DVD. Porém há momentos em que a classe base não é projetada para ser instanciada diretamente pelos clientes. Muitas vezes queremos que elas sejam única e exclusivamente herdadas por classes derivadas, que depois são expostas para os clientes. Estes tipos de classes base são chamados de classes abstratas. Para criar classes abstratas basta usar a palavra abstract quando vamos definir uma classe base. Exemplo:
public abstract class AluguelItem
{
string _titulo;
public string Titulo
{
get { return _titulo; }
set { _titulo = value; }
}
public Boolean VerificaEstoque(string titulo)
{
//codigo para verificar um item no estoque
//returna true para demonstração
return true;
}
}
Neste artigo vimos os conceitos básicos de herança e como ele é usado em programação .Net Framework com C#. É importante que você entenda este conceito de forma eficiente, pois em C# basicamente tudo é orientado a objeto.
Um grande abraço a todos os leitores.