为什么我不能在继承抽象类的类中实现默认接口方法,而该抽象类继承了该接口?

Bar*_*tek 5 c# inheritance

我有一个接口和一个继承该接口的抽象类。

public interface ISomeInterface
{
    int Method()
    {
        return 1;
    }
}

public abstract class SomeAbstractClass : ISomeInterface {}
Run Code Online (Sandbox Code Playgroud)

现在我想实现一个继承的类,SomeAbstractClass它也将实现int Method().

public class SomeClass : SomeAbstractClass
{
    public int Method()
    {
        return 2;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当调用Method()投射SomeClass对象时ISomeInterface,它将显示 1。

ISomeInterface someClass = new SomeClass();
Console.WriteLine($"{someClass.Method()}"); // displays 1
Run Code Online (Sandbox Code Playgroud)

但是如果我添加接口SomeClass

public class SomeClass : SomeAbstractClass, ISomeInterface
{
    public int Method()
    {
        return 2;
    }
}
Run Code Online (Sandbox Code Playgroud)

它将显示 2。

为什么会这样?有没有什么方法可以Method()通过继承SomeAbstractClass而无需编写来声明/实现, ISomeInterface

如果可能的话我也不想修改SomeAbstractClass

我尝试在网上搜索解释,但很难用简单的一句话来解释这个问题。我尝试阅读更多有关默认接口方法的信息,但没有学到任何有意义的东西。

Swe*_*per 2

正如您所注意到的,Method声明的并SomeClass没有实现ISomeInterface.Method。你不能实施ISomeInterface.MethodSomeClass因为SomeAbstractClass已经完全实施了ISomeInterface

通过不声明与 的签名匹配的任何成员ISomeInterface.Method,通过“选择加入”默认实现来SomeAbstractClass完全实现。ISomeInterfaceMethod

这与抽象类通常的工作方式一致 - 如果Method没有默认实现,则空SomeAbstractClass会导致编译器错误。如果您SomeAbstractClass不想实现Method,而让其具体子类来完成这项工作,则需要添加以下内容SomeAbstractClass(无论是否Method有默认实现):

public abstract int Method();
Run Code Online (Sandbox Code Playgroud)

Method有默认实现时,这称为重新抽象

另请参阅这个问题,它是关于如何在抽象类中声明成员,以便它实现非默认接口成员。

请注意,通过将abstract方法添加到SomeAbstractClass,您现在还可以调用Method类型的事物SomeAbstractClass,而以前则不能。


情况是这样的:

// not actually how default interface members are implemented under the hood,
// just for illustration purposes only
public interface ISomeInterface
{
    int Method();
}

public abstract class SomeAbstractClass : ISomeInterface {

    public int Method() => 1;
}

public class SomeClass : SomeAbstractClass
{
    public int Method() => 2; // this method obviously does not implement ISomeInterface.Method!
}
Run Code Online (Sandbox Code Playgroud)