virtuales sobreescribir metodos metodo herencia entre diferencia and abstracto c# inheritance virtual

c# - sobreescribir - Métodos virtuales sin cuerpo.



virtual and override c# (5)

Estaba mirando un código en una clase abstracta:

public virtual void CountX(){} public virtual void DoCalculation() { ...code}

¿Por qué debería declarar un método virtual vacío en una clase abstracta si no es obligatorio anularlo en tipos derivados?


Como @Adam te dijo, hay muchos casos en los que tiene sentido. Cuando creas una clase abstracta, es porque quieres crear una interfaz común para todas las clases derivadas de esa; sin embargo, en ese nivel de herencia no tendrá suficiente información para poder crear código de trabajo para ese método.

Por ejemplo, si crea la clase Figura , con el método getArea () , no podrá escribir el código que calculará correctamente el área para todas las figuras. Tendrá que esperar para escribir el código para el Rectángulo o Círculo (ambos derivados de la Figura ), para poder escribir código de trabajo para ellos.


Cuando declara el método como abstracto, la clase heredada tiene que anular ese método (proporcionar una implementación). Es obligatorio.

Cuando el método se declara como virtual, el heredero puede anular el método y proporcionar una implementación diferente a la predeterminada.


Desde la perspectiva del diseño, esto huele mal e indica que la implementación del diseño se encuentra en un estado inmaduro. Si cada clase que deriva una clase base particular no requiere un método, entonces, por definición, no pertenece a la clase base. Generalmente descubrirá que este método es usado por derivaciones particulares de la clase base y que indica una nueva interfaz o capa de abstracción en su jerarquía de herencia.


Porque si el comportamiento predeterminado es no hacer nada, las clases derivadas pueden querer hacer algo. Es una estructura perfectamente válida.

Permite que su código base lo llame. Tiende a ver diseños similares cuando hay un código "BeforeXXX" y "AfterXXX", en la clase base este código está vacío, pero el método debe estar allí para compilar. En las clases derivadas, este código es opcional, pero necesita ser virtual para ser anulado.

El hecho de que esté en una clase abstracta no debe confundir su comportamiento.

Un ejemplo:

abstract class Base { public void ProcessMessages(IMessage[] messages) { PreProcess(messages); // Process. PostProcess(messages); } public virtual void PreProcess(IMessage[] messages) { // Base class does nothing. } public virtual void PostProcess(IMessage[] messages) { // Base class does nothing. } } class Derived : Base { public override void PostProcess(IMessage[] messages) { // Do something, log or whatever. } // Don''t want to bother with pre-process. }

Si estos métodos (Pre, Post) fueran abstractos, entonces todas las clases derivadas necesitarían implementarlos (probablemente como métodos vacíos): la basura de código que se puede eliminar utilizando métodos virtuales vacíos en la base.


Si es OBLIGATORIO anular y no se pueden escribir lógicas predeterminadas en la clase base, entonces la virtualidad es incorrecta y el método debe ser abstracto. Si la acción predeterminada es no hacer nada, como lo mencionó Adam, hacer un método virtual vacío en la clase base es una estructura perfectamente válida