如果我在派生类上实现了一个接口,如果基础抽象类实现它已经是抽象的话,我想知道是否存在任何(运行时)差异:
public interface IFoo
{
void Bar();
}
public abstract class Base : IFoo
{
public abstract void Bar();
}
public class Derived : Base, IFoo // does this make any difference?
{
public override void Bar()
{
// do something
}
}
在IFoo
上编写“实现”Derived
是否有任何区别,例如当我检查实例是否在运行时实现接口等时?
答案 0 :(得分:2)
请考虑关注您的示例。必须满足以下条件吗?
void f(Base b){
IFoo ifoo = b;
}
因为对象b是Base,所以它必须是IFoo,因为Base实现了IFoo。现在考虑以下内容。
var d = new Derived();
f(d);
由于d是Derived,它是Base,因为派生继承自Base。因此,我们可以将它传递给f,然后将其分配给IFoo,就像我们之前所做的那样。
基本上,因为派生类仍然是它的所有基类,它已经实现了它的所有基类'接口。该语言的设计者承认这一点,并且没有必要重新声明派生类正在实现由其基类实现的接口。
我想也许你的问题出现了,因为你实际上放置了方法体,但这确实不相关。接口的声明是该类型对象的其他使用者的合同。那些消费者并不关心定义方法体的位置,他们关心的只是当他们有一个IFoo时,它有一个带有签名void Bar()
的方法,如前所示,继承必须包括所有接口,因此不需要再次声明它们。
答案 1 :(得分:1)
答案是否。没有区别。
班级Derived
继承自Base
,Base
继承自IFoo
。
因此,在定义班级Base
时,您无需“实施”IFoo
和Derived
。
在定义类Base
时建立层次结构:
public abstract class Base : IFoo
并在您定义Derived
时继续:
public abstract class Derived : Base
通过从{{移除 Base
实施重新定义Base
类,从层次结构中“移除”: IFoo
时,可能会出现唯一的问题1}}类定义如下:
Base
底线是: public abstract class Base
是多余的,因此没有必要。