C# -  
 Compreendendo 
Virtual , Override e new - Conceitos
    
    
    ![]()  | 
    Vou começar este artigo falando de polimorfismo, um importante conceito das linguagens que seguem o paradigma da orientação a objetos. | 
Polimorfismo significa 
muitas formas; na orientação a objetos você pode enviar uma mesma mensagem para 
diferentes objetos e fazê-los responder da maneira correta.  
Você pode enviar uma mensagem mover para cada objeto semelhante a um veiculo e cada um vai se comportar de maneira diferente para atender a sua solicitação.Quando uma mesma mensagem pode ser processada de diferentes formas temos um exemplo de polimorfismo.
"Polimorfismo é o princípio pelo qual duas ou mais classes derivadas de uma 
mesma superclasse podem invocar métodos que têm a mesma identificação 
(assinatura) mas comportamentos distintos, especializados para cada classe 
derivada, usando para tanto uma referência a um objeto do tipo da superclasse"
 
Usando polimorfismo podemos :
Existem dois tipos básicos de polimorfismo:
O Polimorfismo é um conceito das linguagens OOP que incluem a sobrecarga e sobrescrita de métodos.
Assim as palavras chaves Virtual e Override são usadas neste contexto para sobrescrever/substituir um método e a palavra chave new é usada para ocultar um método.
Vamos dar uma espiada com mais atenção nas palavras Overide, Virtual e new da linguagem C# e entender melhor o significado de cada uma delas.
Herança de classe
Considere abaixo a hierarquia de classe A, B e C, onde :
    
 
  | 
    
    using System;
    namespace Polimorfismo
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            a.Teste(); // saída --> "A::Teste()"
                B b = new B();
            b.Teste(); // saída --> "A::Teste()"
                C c = new C();
            c.Teste(); // saída --> "A::Teste()"
                Console.ReadKey();
        }
    }
        public class A
    {
        public void Teste()
        { 
            Console.WriteLine("A::Teste()"); 
        }
    }
        public class B : A { }
        public class C : B { }
}
     | 
    
    ![]()  | 
  
Vamos supor agora que todas essas classes possuam o método Teste() conforme código abaixo:
| 
    using System; 
    
    namespace 
    Polimorfismo1 
                
    a.Teste();    // saida --> "A::Teste()" 
                
    a = new B(); 
                
    b = new C(); 
                
    Console.ReadKey(); 
       
    public class A 
        
    public class B : A 
    
        public class C : B 
  | 
  
Quando executarmos o programa acima ele será executando exibindo a saída conforme mostrada mas também veremos dois alertas na janela Error List:
    ![]()  | 
  
Vemos que o compilador gera os alertas pois a linguagem C# também suporta a ocultação de método.
Para ocultar/esconder o método da classe base da classe derivada basta declarar o método da classe derivada com a palavra chave new.
Vamos então reescrever o código conforme a seguir:
    using System;
    namespace Polimorfismo2
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B();
            C c = new C();
                a.Teste();     // saída --> "A::Teste()"
            b.Teste();     // saída --> "B::Teste()"
            c.Teste();     // saída --> "C::Teste()"
                a = new B();
            a.Teste();     // saída --> "A::Teste()"
                b = new C();
            b.Teste();     // saída --> "B::Teste()"
                Console.ReadKey();
        }
    }
    public class A
    {
        public void Teste() { Console.WriteLine("A::Teste()"); }
    }
        public class B : A
    {
        public new void Teste() { Console.WriteLine("B::Teste()"); }
    }
        public class C : B
    {
        public new void Teste() { Console.WriteLine("C::Teste()"); }
    }
}
     | 
    
    ![]()  | 
  
Analisando o código acima com certeza você deve estar surpreso com o resultado obtido pelo trecho de código abaixo:
       a = new B();
   a.Teste();     // saída --> "A::Teste()"
       b = new C();
   b.Teste();     // saída --> "B::Teste()"
     | 
  
Você deveria estar esperando que a saída fosse:
// saída --> "B::Teste()"
// saída --> "C::Teste()"
Afinal os objetos a e b são referenciados pelos objetos B e C.
Para obter esse resultado temos que sobrescrever o método Teste() da classe base na classe derivada declarando o método da classe base como virtual e o método da classe derivada como override conforme mostra o código abaixo:
    using System;
    namespace Polimorfismo3
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B();
            C c = new C();
            a.Teste();      // saida --> "A::Teste()"
            b.Teste();      // saida --> "B::Teste()"
            c.Teste();      // saida --> "C::Teste()"
            //---------------------------------
            a = new B();
            a.Teste();      // saida --> "B::Teste()"
            b = new C();
            b.Teste();      // saida --> "C::Teste()"
                Console.ReadKey();
        }
    }
        class A
    {
        public virtual void Teste() { Console.WriteLine("A::Teste()"); }
    }
        class B : A
    {
        public override void Teste() { Console.WriteLine("B::Teste()"); }
    }
    class C : B
    {
        public override void Teste() { Console.WriteLine("C::Teste()"); }
    }
}
     | 
    
    ![]()  | 
  
Agora sim temos o resultado esperado pois usando as palavras chave virtual e override ocultamos o método Teste() da classe base nas classes derivadas.
Você também pode misturar a ocultação de métodos com a sobreposição de métodos usando as palavra chaves virtual e new visto que os método da classe derivada podem ser virtual e new ao mesmo tempo.
Este procedimento é necessário quando você quer sobrescrever o método da classe derivada em um próximo nível conforme mostrado a seguir:
    using System;
    namespace Polimorfismo4
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B();
            C c = new C();
                a.Teste(); 	// saida --> "A::Teste()"
            b.Teste(); 	// saida --> "B::Teste()"
            c.Teste(); 	// saida --> "C::Teste()"
                a = new B();
            a.Teste(); 	// saida --> "A::Teste()"
                b = new C();
            b.Teste(); 	// saida --> "C::Teste()"
                Console.ReadKey();
        }
    }
    class A
    {
        public void Teste() { Console.WriteLine("A::Teste()"); }
    }
        class B : A
    {
        public new virtual void Teste() { Console.WriteLine("B::Teste()"); }
    }
        class C : B
    {
        public override void Teste() { Console.WriteLine("C::Teste()"); }
    }
}
     | 
    
    ![]()  | 
  
Concluindo :
E estamos conversados.
Pegue o projeto completo aqui: 
Polimorfismo.zip
Romanos 7:7
Que diremos pois? É a lei pecado? De modo nenhum. Contudo, eu não conheci o pecado senão pela lei; porque eu não conheceria a concupiscência, se a lei não dissesse: Não cobiçarás.Romanos 7:8
Mas o pecado, tomando ocasião, pelo mandamento operou em mim toda espécie de concupiscência; porquanto onde não há lei está morto o pecado.| 
    
    Veja os 
    Destaques e novidades do SUPER DVD Visual Basic 2013 
(sempre atualizado) : clique e confira ! 
 Quer migrar para o VB .NET ? 
 Quer aprender C# ?? 
  | 
  
  
      Gostou ?
 
Compartilhe no Facebook
  
 
Compartilhe no Twitter
  
  
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
C# - Sobrecarga de operadores (Operator Overloading) - Macoratti.net