我似乎无法找到答案,只是想确保它是一个正确的编码标准。我有接口A,它被许多不同的类使用,并且不希望接口A发生变化。我遇到了一个新的需求,它要求许多实现接口A的类需要枚举,但并不是所有的类都需要这个枚举。我不希望不需要这个新枚举的类来实现这个新功能。所以我创建了包含我需要添加的新枚举的接口B.然后我创建了接口B继承接口A,这是我关心的问题,一个接口是否可以继承另一个接口?为了继续我的更改,我然后将需要新枚举的类更改为实现接口B而不是接口A,因为它是由接口B继承的。我考虑在我的类中实现两个接口,但是我正在使用整个代码的接口,并希望只使用一个接口来查看类,而不是两个。
我希望这很清楚(可能很长)但是如果有人能给我一些建议,要么我做得对,要么我做错了请告诉我。
谢谢!
答案 0 :(得分:71)
接口继承是一个很好的工具,但是当接口B真正可以替代接口A时,你应该只使用它,而不仅仅是聚合松散相关的行为。
很难判断它是否适合您的具体案例,但原则上使用这种做法并没有错。您始终可以在一流的API中看到它。从.NET框架中选择一个常见示例:
public interface ICollection<T> : IEnumerable<T>, IEnumerable
答案 1 :(得分:17)
考虑接口是否应该在逻辑上配对,如果你觉得它们相互配合良好,那么绝对使用继承。
让我们看一个例子;
public interface IScanner
{
void Scan();
}
public interface IPrinter
{
void Print();
}
打印机和扫描仪通常是单独的对象,每个对象都有自己的功能,但这两个设备通常在同一设备中配对;
public interface IPhotocopier : IScanner, IPrinter
{
void Copy();
}
IPhotocopier应该继承IScanner和IPrinter是有道理的,因为现在它允许复印机用作扫描仪或打印机(它包含)以及作为复印机的主卷。
现在让我们再看一个界面;
public interface IBlender
{
void Blend();
}
允许IBlender被任何早期接口继承是没有意义的(你会称它们为什么?IBlendingScanner?)。
如果您无法为新界面提供合理的名称,则可能表示您可能不希望在此实例中使用继承。
继承IDisposable之类的接口是一个坏主意,因为这会强制新接口的所有实现实现dispose模式,即使它们没有任何可支配资源。
答案 2 :(得分:9)
从技术上讲,接口不会相互继承。当您创建一个继承自IFoo
的{{1}}时会发生什么,您说任何实现IBar
的类都必须实现IFoo
。
IBar
在此示例中,interface IBar
{
void DoBar();
}
interface IFoo : IBar
{
void DoFoo();
}
接口没有IFoo
方法。大多数情况下,这种区别并不重要,但是当在界面而不是类上使用反射时,它可能会让你感到厌烦。
答案 3 :(得分:6)
当然可以使用接口的继承树,甚至可以使用接口的“多重继承”。是否正确的做法取决于所讨论的接口。如果接口B的实际情况是接口A的扩展或细化,那么继承是有意义的,但如果新的枚举与接口A表达的概念基本无关,我会将它们作为两个独立的接口并具有类需要实现这两个接口。
答案 4 :(得分:2)
IMO这是正确的做法,我认为没有任何问题。
答案 5 :(得分:1)
我认为数据库总是提供一种演示接口的好方法,所以考虑一个接口是否应该继承另一个接口,请看下面的内容,
IMySqlDatabase : IDatabase
MySqlDatabase : IMySqlDatabase
IMsSqlDatabase : IDatabase
MsSqlDatabase : IMsSqlDatabase
MySqlDatabase是IMySqlDatabase,IMySqlDatabase是IDatabase。
现在,如果你需要对你的IDatabase接口进行更改,那么它的孙子(conrete数据库类)可以获得好处,但你不必扩展MySQL和MsSQL(或者甚至更多的DBMS接口)。在你的中间人(IMsSqlDatabase)中,你仍然可以拥有MySQL或Oracle DB不支持的接口功能。