sirve - Herencia de la interfaz C#para la clase abstracta
polimorfismo c# (3)
Supongamos que si tengo una interfaz como se define a continuación:
public interface IFunctionality
{
void Method();
}
e implemento esta interfaz para una clase abstracta como se muestra a continuación:
public abstract class AbstractFunctionality: IFunctionality
{
public void Method()
{
Console.WriteLine("Abstract stuff" + "/n");
}
}
nuevamente tengo una clase concreta que hereda de la clase abstracta como se muestra a continuación:
public class ConcreteFunctionality: AbstractFunctionality
{
public void Method()
{
Console.WriteLine("Concrete stuff" + "/n");
}
}
Ahora tengo el siguiente código,
ConcreteFunctionality mostDerived = new ConcreteFunctionality();
AbstractFunctionality baseInst = mostDerived;
IFunctionality interfaceInst = mostDerived;
mostDerived.Method();
baseInst.Method();
interfaceInst.Method();
La salida que recibo después de la ejecución de este material es la siguiente.
Concrete stuff
Abstract stuff
Abstract stuff
Pero lo que he estado esperando es que la salida sea "Cosas concretas" en los tres casos, ya que lo que estoy haciendo aquí es asignar la referencia de ConcreteFunctionality
a las variables de tipo AbstractFunctionality
e IFunctionality
.
Que esta pasando internamente La amabilidad de aclarar.
Aquí:
public class ConreteFunctionality:AbstractFunctionality
{
public void Method()
{
Console.WriteLine("Concrete stuff" + "/n");
}
}
... no estás anulando el método existente . Está creando un nuevo método que oculta el existente. (También debería recibir una advertencia sugiriendo el uso del new
modificador si realmente desea este comportamiento.) La interfaz se implementó en AbstractFunctionality
, por lo que la tabla de asignación de interfaz se refiere al método en esa clase.
Ahora si vuelve a implementar la interfaz:
public class ConcreteFunctionality : AbstractFunctionality, IFunctionality
... entonces el mapeo de interfaz se referirá al método en ConcreteFunctionality
y obtendrá el comportamiento que espera para la llamada a través de la interfaz (es decir, su tercera llamada) pero aún así obtendrá la implementación en AbstractFunctionality
para su segunda llamada.
Sería en general más limpio y más conservador de la cordura hacer virtual el método en AbstractFunctionality
, y anularlo en ConcreteFunctionality
. De esa forma, utilizará la implementación ConcreteFunctionality
en todos los casos.
Debes definir las clases como:
public abstract class AbstractFunctionality:IFunctionality
{
public virtual void Method()
{
Console.WriteLine("Abstract stuff" + "/n");
}
}
public class ConreteFunctionality:AbstractFunctionality
{
public override void Method()
{
Console.WriteLine("Concrete stuff" + "/n");
}
}
Como no ha redefinido Method () en ConreteFunctionality, el entorno de tiempo de ejecución ejecuta Method () asociado con el objeto AbstractFunctionality ya que aquí no puede aplicar polimorfismo dinámico. Al introducir virtual
y override
el entorno de tiempo de ejecución ejecuta el método sobrescrito en la clase hija.
Le faltan palabras clave virtual
y override
. Sin esto no obtienes funciones virtuales.
Puede marcar Method
en AbstractFunctionality como virtual
y marcar el Method
en ConreteFunctionality
como override
. Como mihirj ha demostrado.
Problemas similares abordados: ¿por qué los métodos de la interfaz C # no se declaran abstractos o virtuales?