Breve explicação de métodos Virtuais no C#

Para definir métodos Virtuais, vou citar esta frase retirada do site da Microsoft “A palavra-chave virtual é usada para modificar uma declaração de método, propriedade, indexador ou evento e permitir que ela seja substituída em uma classe derivada.”
Exemplo:

public virtual double Area()   
{  
    return x * y;  
} 

Ainda do site da Microsoft podemos ler que “A implementação de um membro virtual pode ser alterada por um membro de substituição em uma classe derivada.”

E qual a diferença entre Virtual e Abstrato ?

Existe uma semelhança entre métodos virtuais e métodos abstratos. Já que ambos serão alterados pela classe derivada.
Para entendermos a diferença pontuei as explicações abaixo.

Uma função abstrata não pode ter funcionalidade. Estou basicamente dizendo, qualquer classe filho deve dar sua própria versão deste método, no entanto, é muito geral para tentar implementar na classe pai.
Sobre classes e métodos abstratos podemos dizer:
– Apenas classes abstratas podem ter membros abstratos.
– Uma classe não abstrata que herda de uma classe abstrata deve substituir seus membros abstratos.
– Um membro abstrato é implicitamente virtual.
– Um membro abstrato não pode fornecer nenhuma implementação.
– Não é necessário que um método abstrato tenha que ser implementado em uma classe filha, se a classe filha também for abstrata.

Uma função virtual, basicamente apresenta uma funcionalidade que pode ou não ser boa o suficiente para a classe filha. Então, se é bom o suficiente, use este método, se não, em seguida, substituir-me e fornecer sua própria funcionalidade.

Com base no exemplo do curso Programação no Jump Start de C# alterei o código para deixar o mais didático. Este exemplo demonstra como funciona a herança e alteração de método Virtual

using System;
					
public class Program
{
	public static void Main()
	{
		var baseClass = new MyBaseClass();
		var myOverride = new MyOverrideClass();
		var myNew = new MyNewClass();
		var myOverWrite = new MyOverWriteClass();

		// => Just call method NameClass of all objects
		baseClass.NameClass();
		myOverride.NameClass();
		myNew.NameClass();
		myOverWrite.NameClass();

		Console.WriteLine("---");

		// => Cast all to 'MyBaseClass'
		baseClass.NameClass(); // There is no cast here, already 'MyBaseClass'
		((MyBaseClass)myOverride).NameClass();
		((MyBaseClass)myNew).NameClass();
		((MyBaseClass)myOverWrite).NameClass();

		Console.ReadLine();
	}
	
    internal class MyBaseClass
    {
        internal virtual void NameClass()
        {
            Console.WriteLine("MyBaseClass");
        }
    }

    internal class MyOverrideClass : MyBaseClass
    {
        internal override void NameClass()
        {
            Console.WriteLine("MyOverrideClass");
        }
    }

    internal class MyNewClass : MyBaseClass
    {
        internal new void NameClass()
        {
            Console.WriteLine("MyNewClass");
        }
    }

    internal class MyOverWriteClass : MyBaseClass
    {
        internal void NameClass()
        {
            Console.WriteLine("MyOverWriteClass");
        }
    }
}

Ao executar este exemplo é apresentada a seguinte saída.

MyBaseClass
MyOverrideClass
MyNewClass
MyOverWriteClass
---
MyBaseClass
MyOverrideClass
MyBaseClass
MyBaseClass

Este código é um exemplo do comportamento que acontece quando temos um método “override” sobrepondo um método “virtual”. Mesmo mudando o tipo do objeto para MyBaseClass, ainda temos que a chamada que foi implementada na classe filha.

Este é um ponto importante de atenção, pois seria de esperar que depois de mudar o tipo do objeto, ele vai fazer referencia ao método da classe ao qual lhe foi atribuído, porem com o “override” este método foi alterado já na classe pai desta instancia de objeto.

Qualquer dúvida ou dicas, entre em contato: leandrolt@gmail.com

Leave a Reply

Your email address will not be published. Required fields are marked *