2010-07-14 13 views

Respuesta

16

Al declarar un método como virtual, usted está indicando su intención que el método se puede reemplazar en una clase derivada.

Al declarar su método de ejecución como override, su son indicando su intención que está sustituyendo un método virtual.

Al requerir que se utilice la palabra clave override para anular un método virtual, los diseñadores del lenguaje fomentan la claridad, al exigirle que exprese sus intenciones.

+0

¿Por qué no marcarlo como 'abstracto' y forzar la anulación? –

+1

@George: Porque solo puedes usar el modificador abstracto en clases abstractas. –

+3

@George Stocker - Porque es posible que no desee marcar toda su clase como abstracta (la clase necesita que el modificador abstracto tenga métodos abstractos). –

5

Porque hace que el código sea más legible:

class Derived : Base 
{ 
    void Foo(); 
} 

En C++, Foo puede o no ser un método virtual, no podemos decir mirando a la definición. En C#, sabemos que un método es virtual (o no lo es) porque hay una palabra clave virtual o de anulación.

El comentario de Jason a continuación es una mejor respuesta.

(editado para mayor claridad)

+1

... y le da a Intellisense la capacidad de ayudarnos a anular un método. Escriba "anular" e Intellisense aparece con una opción e incluso completa la firma de método completa para nosotros. ¿Qué tan maravilloso es eso? – Tergiver

+5

... y, lo que es más importante, permite que el compilador nos diga cuándo cometemos un error (por ejemplo, si agrega un parámetro al método de clase base en C++, rompe todas las clases derivadas pero no tiene forma de saberlo) - una causa de algunos realmente desagradables para rastrear errores, porque los bits del comportamiento de la clase derivada simplemente dejan de funcionar silenciosamente. En C# da un error por cada anulación que ya no anula nada) –

+0

_ "En C++ podría ser, podemos" Dígalo mirando la definición. "_ - Al observar la definición, podemos decir que no es C++ en absoluto. – stakx

11

Si no agrega la palabra clave override, el método estará oculto (como si tuviera la palabra clave new), no se anula.

Por ejemplo:

class Base { 
    public virtual void T() { Console.WriteLine("Base"); } 
} 
class Derived : Base { 
    public void T() { Console.WriteLine("Derived"); } 
} 

Base d = new Derived(); 
d.T(); 

Este código imprime Base. Si agrega override a la implementación Derived, el código se imprimirá Derived.

No puede hacer esto en C++ con un método virtual. (There is no way to hide a C++ virtual method without overriding it)

+0

¿Por qué tanta gente no sabe sobre el comportamiento 'nuevo' predeterminado? – Dykam

+1

Acepto que esto no debería ser legal y debería arrojar un error en lugar de una advertencia. (Editar: Alguien eliminó su comentario sobre este). – Dykam

+0

Warings as errors ¡FTW! –

1

No se deben anular todos los métodos virtuales, aunque todos los métodos abstractos deberían (y deben) serlo. En cuanto a por qué la palabra clave 'anular' es explícita, es porque la anulación y la ocultación se comportan de manera diferente. Un método de ocultación no se llama a través de una referencia a una clase base, mientras que un método reemplazado sí lo es. Esta es la razón por la que el compilador advierte específicamente sobre cómo debe usar la palabra clave 'nueva' en el caso en que se oculta en lugar de anularla.

10

Es porque los miembros del equipo C# son todos programadores expertos en C++. Y sepa cuán incipiente es esta falla en particular:

class Base { 
protected: 
    virtual void Mumble(int arg) {} 
}; 

class Derived : public Base { 
protected: 
    // Override base class method 
    void Mumble(long arg) {} 
}; 

Es mucho más común de lo que pueda pensar. La clase derivada siempre se declara en otro archivo de código fuente. Normalmente no se equivoca al momento, sucede cuando se refactoriza. El código no funciona, el código funciona bastante normal, simplemente no hace lo que espera que haga. Puedes mirarlo por una hora o un día y no ver el error.

Esto nunca puede suceder en un programa C#. Incluso C++ administrado adoptó esta sintaxis, rompiendo intencionalmente con la sintaxis nativa de C++. Siempre una elección valiente. IntelliSense quita el aguijón a la verborrea extra.

Hay muchos ajustes de sintaxis en C# que se parecen a este tipo de sintaxis de prevención de errores.


EDIT: y el resto de la comunidad C++ acordó y aprobó la anulación palabra clave en la nueva especificación del lenguaje C++ 11.

+1

+1 La mejor respuesta IMO porque explica el "por qué" detrás de la decisión del diseño del lenguaje en lugar de "cómo funcionan las llamadas virtuales", como lo hacen las respuestas con una calificación más alta ... PS. @Hans, parece que estoy tropezando con muchas respuestas pertinentes escritas por ti estos días :) –

0

No hay necesidad de anular explícitamente un método virtual en una clase derivada. Marcar un método virtual solo habilita la anulación.

Cuestiones relacionadas