C # - OOP - Herança (mais um pouco sobre ela)
Vamos rever alguns conceitos sobre herança na linguagem C#. |
Se você acha que sabe tudo sobre o assunto pode sair do artigo senão acompanhe...
Herança
Sintaxe:
Classe Base = A (classe Pai)
class A { public int a; public A() { Console.WriteLine("construtor A"); } public void M(string nome) { Console.WriteLine("sou o " + nome); } } |
SubClasse = B (classe filha, classe derivada)
B : A (herda de A, estende A)
class
B : A { int b; public B() { Console.WriteLine("construtor B"); } public void J() { Console.WriteLine("sou J "); } } |
Métodos
herdados de System.Object Equals Testa se dois objetos são iguais GetHashCode Retorna o código de hash para o objeto GetType Retorna informação sobre a classe do objeto ToString Retorna o objeto como string |
Vamos executar o código abaixo para ver o resultado:
class Program { static void Main(string[] args) { B b = new B(); b.M("Macoratti"); Console.WriteLine("Executei Main"); Console.ReadKey(); } } |
Observe que antes de executar o seu construtor, o construtor da classe A foi executado.
Executando o construtor com parâmetros da classe base
Vamos definir um construtor com parâmetros na classe base A e mostrar como executá-lo na classe derivada.
Classe base A:
class A { public int a; //construtor da classe base public A() { Console.WriteLine("construtor A"); } //construtor com parâmetros da classe base public A(string nome) { Console.WriteLine("Sou o construtor com parâmetros da classe A " + nome); } public void M(string nome) { Console.WriteLine("sou o " + nome); } } |
classe derivada B:
class B : A { int b; //construtor da classe derivada public B() { Console.WriteLine("construtor B"); } //declara o construtor da classe derivada herdando da classe base public B(string nome) : base(nome) { } public void J() { Console.WriteLine("sou J "); } } |
Executando o construtor da classe base:
class Program { static void Main(string[] args) { B b = new B(); //executa construtor c/parâmetros da classe base B b1 = new B("Macoratti"); b.M("Macoratti"); Console.WriteLine("Executei Main"); Console.ReadKey(); } } |
Verificando e alterando o tipo de um objeto
O operador is é usado para verificar se um objeto é de uma determinada classe ou descendente desta classe, retornando verdadeiro ou falso;
O operador as é utilizado para alterar o tipo da referência de um objeto. Quando não é possível a alteração é retornado null.
Vamos definir mais uma classe chamada C que herda da classe B conforme o código a seguir:
class C : B { public int c; //construtor da classe base public C() { Console.WriteLine("construtor C"); } //método X() da classe C public void X(string nome) { Console.WriteLine("Classe C: sou o " + nome); } } |
Temos então que C herda de B que herda de A logo C herda de A.
Quando instanciamos um objeto da classe C poderemos ver no Intellisense que ele herda :
Vamos utilizar os operadores is e as para verificar e alterar o tipo de um objeto executando o código abaixo:
class Program { C c = new C(); //verificando se um objeto é de uma determinada classe //ou descendente desta classe(operador is) A a = new A(); if (a is A) { Console.WriteLine(" a é um tipo " + a.GetType()); } a = new B(); if (a is B) { Console.WriteLine(" a é um tipo " + a.GetType()); } a = new C(); if (a is C) { Console.WriteLine(" a é um tipo " + a.GetType()); } // alterando o tipo da referência do objeto 'a' para classe A // e usando o método M (operador as) (a as A).M("Macoratti"); // alterando o tipo da referência do objeto 'a' para classe B // e usando o método J (operador as) (a as B).J(); Console.WriteLine("Executei Main"); Console.ReadKey(); } |
Sobrescrevendo um método da classe base
Para sobrescrever um método da classe base o mesmo deve ser declarado com a palavra-chave virtual na classe base.
Na classe derivada o método sobrescrito deve usar a palavra-chave override.
Definindo o método virtual classe base B:
class
B : A { int b; //construtor da classe derivada public B() { Console.WriteLine("construtor B"); } //declara o construtor da classe derivada herdando da classe base public B(string nome) : base(nome) { }
//método virtual |
Sobrescrevendo o método calculaB() na classe derivada C usando a palavra-chave override:
class C : B { public int c; //construtor da classe base public C() { Console.WriteLine("construtor C"); } //método X() da classe C public void X(string nome) { Console.WriteLine("Classe C: sou o " + nome); }
//sobrescrevendo o método CalculaB() |
Executando o código para verificação:
class Program { static void Main(string[] args) { C c = new C(); Console.WriteLine(" 5 * 5 = " + c.calculaB(5, 5)); Console.WriteLine("Executei Main"); Console.ReadKey(); } } |
Note que o método calculaB(5,5) retornou o valor da multiplicação definido no método sobrescrito na classe C e não o método da classe base B.
Observe que como C herda de B que herda A foi executado o construtor da classe A e da classe B antes do construtor da classe C.
Escondendo métodos da classe base
Se um método da classe derivada possuir a mesma assinatura de um método da classe base mas não for definido com a palavra-chave override ele irá esconder o método da classe base.
Esse comportamento pode ser o que você realmente deseja ter e a classe será compilada sem erros mas o compilador irá emitir um aviso de alerta perguntando se este é o comportamento esperado.
Para esconder um método da classe base sem emitir o aviso do compilador você deve usar a palavra-chave new no método da classe derivada.
Classe Base = A (classe Pai)
class A { public int a; public A() { Console.WriteLine("construtor A"); } public void M(string nome) { Console.WriteLine("sou o " + nome); } public void Y() { Console.WriteLine("sou o método Y da classe base A"); } } |
SubClasse = B (classe filha, classe derivada)
B : A (herda de A, estende A)
class
B : A { int b; public B() { Console.WriteLine("construtor B"); } public void J() { Console.WriteLine("sou J "); } public new void Y() { Console.WriteLine("sou o método Y da classe derivada B"); } } |
A classe derivada B possui o método Y() que irá esconder o método Y() da classe base A. Nesta caso estamos usando a palavra-chave new no método da classe derivada.
Se a palavra new não for usada a classe será compilada mas o aviso abaixo será emitido pelo compilador:
Warning 4 'C_heranca1.B.Y()'
hides inherited member 'C_heranca1.A.Y()'. Use the new
keyword if hiding was intended. |
Aguarde mais artigos sobre conceitos da programação orientada a objetos.
"Ele, porém, respondendo, disse: Toda a planta, que meu Pai Celestial não plantou, será arrancada." Mateus 15:13
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#