C#接口继承到抽象类

时间:2013-01-25 07:03:11

标签: c# oop interface abstract-class concrete

假设我有一个如下定义的接口:

public interface IFunctionality
{
    void Method();       
}

我为抽象类实现了这个接口,如下所示:

public abstract class AbstractFunctionality: IFunctionality
{
    public void Method()
    {
        Console.WriteLine("Abstract stuff" + "\n");
    }       
}

我还有一个具体的类,它继承自抽象类,如下所示:

public class ConcreteFunctionality: AbstractFunctionality
{
    public void Method()
    {
        Console.WriteLine("Concrete stuff" + "\n");
    }
}

现在我有以下代码,

ConcreteFunctionality mostDerived = new ConcreteFunctionality();
AbstractFunctionality baseInst = mostDerived;
IFunctionality interfaceInst = mostDerived;
mostDerived.Method();
baseInst.Method();
interfaceInst.Method();

执行此操作后我得到的输出如下:

Concrete stuff
Abstract stuff
Abstract stuff

但是我一直期待输出是"混凝土材料"在所有三种情况下,我在这里所做的是将ConcreteFunctionality的引用分配给AbstractFunctionalityIFunctionality类型的变量。

内部发生了什么。请澄清。

3 个答案:

答案 0 :(得分:74)

下面:

public class ConreteFunctionality:AbstractFunctionality
{
    public void Method()
    {
        Console.WriteLine("Concrete stuff" + "\n");
    }
}

...您没有覆盖现有的方法。您正在创建一个方法,隐藏现有方法。 (你也应该收到警告,如果你真的想要这种行为,建议使用new修饰符。)接口是在AbstractFunctionality中实现的,所以接口映射表引用的方法是类。

现在,如果您重新实现界面:

public class ConcreteFunctionality : AbstractFunctionality, IFunctionality

...然后接口映射将引用ConcreteFunctionality中的方法,您将通过接口(即第三次调用)获得您期望的行为,但是你仍然可以在AbstractFunctionality中获得第二次电话的实施。

AbstractFunctionality虚拟中使用该方法通常更清晰,更保持理智,并在ConcreteFunctionality中覆盖它。这样,它将在所有情况下使用ConcreteFunctionality实现。

答案 1 :(得分:30)

您需要将类定义为:

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");
    }
}

由于您没有覆盖ConreteFunctionality中的Method(),因此运行时环境执行与AbstractFunctionality对象关联的Method(),因为它不能在此处应用动态多态。引入virtualoverride使运行时环境在子类中执行overriden方法。

答案 2 :(得分:14)

您缺少virtualoverride个关键字。如果没有这个,你就不会得到虚函数。

您可以将AbstractFunctionality中的Method标记为virtual,并将Method中的ConreteFunctionality标记为override。正如mihirj所示。

Why are C# interface methods not declared abstract or virtual?

中解决了类似的问题