假设我们有两个接口:
interface Ilayer1 : Ilayer2
{
string testMethod1();
}
interface Ilayer2
{
string testMethod2();
}
class A: Ilayer1
{
...//implement all methods of Ilayer 1 and Ilayer2
}
所以我的问题是:
Ilayer1
通过继承Ilayer2
得到了什么?Ilayer1
和Ilayer2
之间的继承关系,让A类实现两个接口为class A: Ilayer1, Ilayer2
它与类之间的继承具有相同的语义。 在OOP世界中,派生类型在基类型的更具体版本时继承基类型 - 无论此类型是接口还是类,原则保持不变。
这是.Net框架的一个例子:IList
接口继承了继承ICollection接口的IEnumerable接口。
IEnumerable
接口提供了使用GetEnumerator()
循环枚举所需的foreach
方法。
ICollection
增加了新功能:Count
属性和CopyTo
方法。
IList
增加了更多功能 - 索引器,Add
和Remove
方法等等。
因此,IList
是一种更具体的ICollection
类型,这是一种更具体的IEnumerable
类型。
接口可以相互继承的事实意味着您也可以在接口上拥有polymorphic视角,而不仅仅是类 - 这有助于在处理彼此继承的多个接口时非常简化代码。
这样做的另一个好处是,您可以在接口上声明扩展方法,并在任何实现此接口的类上使用它,无论是直接还是间接地通过实现继承它的接口 - 就像在类中一样。
至于为什么不删除继承并分别实现两个接口的问题 - 如果接口不相关则有意义 - 例如,在Control
类(在System.Windows.Forms中) - 它实现了许多接口,像IDropTarget
和IComponent
这些无关。
一个真实的例子:
interface IShape
{
double X { get; }
double Y { get; }
}
interface IAreaShape : IShape
{
double GetArea();
}
interface IPerimeterShape : IShape
{
double GetPerimeter();
}
现在假设你有一个Rectangle : IAreaShape, IPerimeterShape
形状,你可以计算它的面积和周长。当你有一个类型为IAreaShape
或IPerimeterShape
的物体时,它必须是一个IShape
。这是第二个问题的答案。
现在,对于你的第一个问题,假设,为了举例,我们有一个Circle
,我只能计算面积而不是周长。在这种情况下,我们只是声明它Circle : IAreaShape
。
对于管理:List<IShape> shapes
可以采用Circle和Rectangle以及任何东西,只要它们实现IShape
(或任何派生类型的IShape
)。如果您不在乎是否可以计算其面积或周长,则可以执行此操作,但始终可以获得其X和Y坐标。
Ilayer1
继承了Ilayer2
,这意味着任何实施Ilayer1
的人都需要实施testMethod1()
和testMethod2()
。为什么呢?为什么不?因为我们可以?我认为在具有大量接口的大型项目中,如果你需要指定一些类正在单独实现的所有接口,它会变得相当繁琐(尽管在良好的SOLID设计中,一个类通常不应该实现多个接口)。因此,您可以通过让接口实现其他接口来“分组”接口。你也可以通过使用接口继承来'version' an interface。接口可以从其他接口继承。一个类可能通过它继承的基类或通过其他接口继承的接口多次包含一个接口。但是,只有当类将接口声明为类的定义(
class ClassName : InterfaceName
)的一部分时,该类才能提供接口的实现。如果继承接口是因为您继承了实现接口的基类,则基类提供接口成员的实现。但是,派生类可以重新实现任何虚拟接口成员,而不是使用继承的实现。 Source