关于oop:C#接口继承Abstract类

C# Interface Inheritance to Abstract class

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

1
2
3
4
public interface IFunctionality
{
    void Method();      
}

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

1
2
3
4
5
6
7
8
public abstract class AbstractFunctionality: IFunctionality
{
    public void Method()
    {
        Console.WriteLine("Abstract stuff" +"
"
);
    }      
}

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

1
2
3
4
5
6
7
8
public class ConcreteFunctionality: AbstractFunctionality
{
    public void Method()
    {
        Console.WriteLine("Concrete stuff" +"
"
);
    }
}

现在我有了以下代码,

1
2
3
4
5
6
ConcreteFunctionality mostDerived = new ConcreteFunctionality();
AbstractFunctionality baseInst = mostDerived;
IFunctionality interfaceInst = mostDerived;
mostDerived.Method();
baseInst.Method();
interfaceInst.Method();

我在执行这些东西之后得到的输出如下。

1
2
3
Concrete stuff
Abstract stuff
Abstract stuff

但我一直希望在这三种情况下,输出都是"具体的东西",正如我在这里所做的,是将ConcreteFunctionality的引用分配给AbstractFunctionalityIFunctionality类型的变量。

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


在这里:

1
2
3
4
5
6
7
8
public class ConreteFunctionality:AbstractFunctionality
{
    public void Method()
    {
        Console.WriteLine("Concrete stuff" +"
"
);
    }
}

…您没有重写现有的方法。您正在创建一个隐藏现有方法的新方法。(如果您真的想要这个行为,也应该得到一个警告,建议使用new修饰符。)接口是在AbstractFunctionality中实现的,因此接口映射表引用了该类中的方法。

现在,如果重新实现接口:

1
public class ConcreteFunctionality : AbstractFunctionality, IFunctionality

…然后,接口映射将引用ConcreteFunctionality中的方法,您将通过接口(即第三次调用)获得预期的调用行为,但第二次调用仍将获得AbstractFunctionality中的实现。

AbstractFunctionality中的方法变为虚拟的,并在ConcreteFunctionality中覆盖它,通常会更干净、更健全。这样,它将在所有情况下使用ConcreteFunctionality实现。


您需要将类定义为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public abstract class AbstractFunctionality:IFunctionality
{
    public virtual void Method()
    {
        Console.WriteLine("Abstract stuff" +"
"
);
    }      
}

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

由于您没有在ConretFunctionality中重写method(),因此运行时环境将执行与AbstractFunctionality对象关联的method(),因为它不能在此处应用动态多态性。引入virtualoverride使得运行时环境可以在子类中执行overriden方法。


您缺少virtualoverride关键字。没有这个你就不能得到虚拟功能。

在抽象功能中可以将Method标记为virtual,在ConreteFunctionality中可以将Method标记为override。正如Mihirj所示。

类似的问题在-为什么C接口方法没有声明为抽象的或虚拟的?