2011-10-24 30 views
14

¿Por qué usamos override y virtual si da el mismo efecto cuando no usamos override y virtual?¿Por qué usamos Virtual y Override?

ejemplo 1:

class BaseClass 
{ 
    public virtual string call() 
    { 
     return "A"; 
    } 
} 

class DerivedClass : BaseClass 
{ 
    public override string call() 
    { 
     return "B"; 
    } 
} 

salida: B

Ejemplo 2:

class BaseClass 
{ 
    public string call() 
    { 
     return "A"; 
    } 
} 

class DerivedClass : BaseClass 
{ 
    public string call() 
    { 
     return "B"; 
    } 
} 

y la salida sigue siendo el mismo:

salida: B

para ejecutar la prueba:

class Program 
{ 
    static void Main(string[] args) 
    { 
     DerivedClass dc = new DerivedClass(); 
     Console.WriteLine(dc.call()); 
     Console.ReadKey(); 
    } 
} 

¿El compilador añadir virtual y anula automáticamente en tiempo de compilación?

Estaría encantado de que alguien me explicara el motivo por el que se usa el uso virtual y la anulación.

+1

Usted obtendrá un resultado diferente si canst DerivedClass a clase base antes de llamar a añadir: 1 => 2 y 2 => 1 – Peter

+0

@CD .. no hay duplicado, es acerca de la "anulación y virtual" – Racooon

+2

sería realmente mucho mejor publicar ejemplos que .... compilados. –

Respuesta

20

(nota, que estoy haciendo caso omiso de los errores de compilación en silencio)

Ahora hacemos:

BaseClass obj = new DerivedClass(); 
Console.WriteLine(obj.call()); 

Sin virtual, esto imprimirá A, cuando en realidad un DerivedClass debería estar escribiendo B. Esto se debe a que simplemente ha llamado a la implementación BaseClass (ya que obj se escribe como BaseClass y no se define polimorfismo).

+0

Aquí hay un buen enlace sobre esto (probablemente sea mejor, pero fue el primero que encontré cuando busqué escondite implícito) http://geekswithblogs.net/BlackRabbitCoder/archive/2010/06/24/c-fundamentals-beware-of -implicit-hiding.aspx –

+0

Imprime igual, y no importa si usa override y virtual. Creo que el compilador lo agrega en el tiempo de compilación. – Racooon

+3

@Vural mira detenidamente la diferencia entre mi escenario y el tuyo. Ahora cambie su código a 'BaseClass bc = new DerivedClass(); Console.WriteLine (bc.call()); '. Para enfatizar: no *** no *** agregar esto automáticamente en tiempo de compilación; simplemente, estás probando algo diferente. –

5

Virtual y override son un mecanismo básico de herencia en la programación orientada a objetos. Esto es quizás lo más importante de entender cuando usa clases en un lenguaje como C# o Java.

http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)

La herencia permite la reutilización de código adición de nuevos campos, propiedades y métodos o métodos que sustituyen y propiedades de las clases definidas anteriormente.

Virtual y Override le permiten reemplazar el contenido de un método, y cuando digo replace, digo replace.

Le propondría un buen ejemplo.

public class MyClassEnglish 
{ 
    public virtual string SomethingToSay() 
    { 
     return "Hello!"; 
    } 

    public void WriteToConsole() 
    { 
     Console.WriteLine(this.SomethingToSay()); 
    } 
} 

public class MyClassItalian : 
    MyClassEnglish 
{ 
    public override string SomethingToSay() 
    { 
     return "Ciao!"; 
    } 
} 

int main() 
{ 
    MyClassItalian it = new MyClassItalian(); 

    it.WriteToConsole(); 
} 

Si omite virtual y anula, MyClassItalian imprimirá "¡Hola!" y no "Ciao!"

En su ejemplo muestra una técnica de remedo, pero el compilador debe darle una advertencia. Debe agregar la palabra clave "nueva" si desea ocultar un método en una clase base. ¡Ocultar un método no está anulando! Es solo esconderse.

Un posible uso que me viene a la mente es que puede usarse cuando se necesita algún tipo de optimización, por ejemplo.

public abstract class MySpecialListBase 
{ 
    public int Count() 
    { 
     return this.GetCount(); 
    } 

    protected abstract int GetCount(); 
} 

public sealed class MySpecialArrayList : MySpecialListBase 
{ 
    int count; 

    public new int Count() 
    { 
     return this.count; 
    } 

    protected override int GetCount() 
    { 
     return this.count; 
    } 
} 

Ahora ... Puede utilizar MySpecialListBase en todo el código, y cuando se llama a la Count() se llamará al método virtual GetCount(). Pero si usa simplemente MySpecialArrayList llamará al Conteo optimizado() que no es virtual y que solo devuelve un campo, aumentando el rendimiento.

// This works with all kind of lists, but since it is a more general purpose method it will call the virtual method.  
public void MyMethod(MySpecialListBase list) 
{ 
    Console.WriteLine(list.Count()); 
} 

// This works only with MySpecialArrayList, and will use the optimized method. 
public void MyMethod(MySpecialArrayList list) 
{ 
    Console.WriteLine(list.Count()); 
} 
1

mejor ejemplo que puedo pensar en que esto es útil es cuando se crea su propio objeto (clase) y hay que añadir una lista de ese objeto a un cuadro combinado.

Cuando agrega su objeto al cuadro combinado, desea poder controlar qué texto se muestra para cada elemento. Object.toString es un método virtual. http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx y debido a esto puede anular ese método y establecer .toString para mostrar la información correcta sobre su objeto anulándolo.

public MyClass() 
{ 
    private int ID; 
    public override string ToString() 
    { 
     return "My Item:" + ID; 
    } 
} 
0

el reemplazo de métodos:

Cuando defina o implementar un método virtual en una clase padre y luego volver a colocarlo en una clase descendiente.

Cuando decide declarar un método como virtual, está dando permiso a las clases derivadas para extender y anular el método con su propia implementación. Puede hacer que el método extendido también llame al código del método principal.

En la mayoría de los lenguajes OO también puede optar por ocultar un método principal. Cuando introduce una nueva implementación del mismo método con la misma firma sin anular, está ocultando el método principal.

C# Overriding En C#, especifica un método virtual con la palabra clave virtual en una clase principal y la extiende (o la reemplaza) en una clase descendiente utilizando la palabra clave override.

Utilice la palabra clave base en el método descendiente para ejecutar el código en el método principal, es decir, base.SomeMethod().

Sintaxis Ejemplo:

class Robot 
{ 
    public virtual void Speak() 
    { 
    } 
} 

class Cyborg:Robot 
{ 
    public override void Speak() 
    { 
    } 
} 

Override detalles No se puede reemplazar un método no virtual regular, ni un método estático. La primera versión del método principal debe ser virtual o abstracta. Puede anular cualquier método principal marcado como virtual, abstracto o anular (ya anulado). Los métodos deben tener la misma firma. Los métodos deben tener la misma visibilidad (el mismo nivel de acceso). Use la palabra clave base para referirse a la clase principal como en base.SomeMethod(). C# Override Ejemplo El siguiente fragmento de código demuestra el uso de virtual y override para reemplazar un método principal en una clase descendiente.

using System; 

class Dog 
{ 
    public virtual void Bark() 
    { 
     Console.WriteLine("RUFF!"); 
    } 
} 

class GermanShepard:Dog 
{ 
    public override void Bark() 
    { 
     Console.WriteLine("Rrrrooouuff!!"); 
    } 
} 

class Chiuaua:Dog 
{ 
    public override void Bark() 
    { 
     Console.WriteLine("ruff"); 
    } 
} 
class InclusionExample 
{ 
    public static void Main() 
    { 
     Dog MyDog=new Dog();  
     MyDog=new GermanShepard(); 
     MyDog.Bark(); // prints Rrrrooouuff!! 

     MyDog=new Chiuaua(); 
     MyDog.Bark(); // prints ruff; 
    } 
} 

Ocultación de un método con Nueva utilizar la nueva palabra clave para introducir una nueva implementación de un método de matriz (esto oculta el método de los padres). Puede ocultar un método sin usar nuevo, pero obtendrá una advertencia del compilador. Usar nuevo suprimirá la advertencia.

Los modificadores nuevos y modificadores tienen diferentes significados. El nuevo modificador crea un nuevo miembro con el mismo nombre, firma y visibilidad, y oculta el miembro original. El modificador de modificación amplía la implementación de un miembro heredado y le permite implementar un polimorfismo basado en herencia.

Evitar la introducción de nuevos miembros: a veces hay razones claras para introducir un nuevo método con el mismo nombre, firma y visibilidad de un método principal. En esos casos claros, la introducción de un nuevo miembro es una característica poderosa. Sin embargo, si no tiene una razón clara, entonces evite introducir una nueva versión de un método nombrando el nuevo método como algo único y apropiado.

class Robot : System.Object 
{ 
    public void Speak() 
    { 
    MessageBox.Show("Robot says hi"); 
    } 
} 

class Cyborg : Robot 
{ 
    new public void Speak() 
    { 
    MessageBox.Show("hi"); 
    } 
} 

llamar a la clase Version Base Una tarea común en OO es extender un método mediante la ejecución primero el código del método de los padres y a continuación, añadir código. Use la palabra clave base para referirse a la clase padre como en base.SomeMethod().

class Robot : System.Object 
{ 
    public virtual void Speak() 
    { 
     MessageBox.Show("Robot says hi"); 
    } 
} 
class Cyborg : Robot 
{ 
    public override void Speak() 
    { 
     base.Speak(); 
     MessageBox.Show("hi"); 
    } 
}