.net 一个接口是否应该继承另一个接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1688808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:32:29  来源:igfitidea点击:

Should one interface inherit another interface

.netoopinheritance

提问by ajrawson

I can't seem to find an answer on this and just want to make sure it's an ok coding standard. I have Interface A that is used by many different classes and don't want interface A to change. I came across a new requirement that will require an enum to be needed by many of the classes that Implement Interface A, but not all the classes need this enum. I don't want the classes that don't require this new enum to Implement this new functionality. So I created Interface B that contains the new enum that I needed to add. I then made Interface B Inherit Interface A and this is my concern, Is it ok for one Interface to Inherit another Interface? To continue with my changes, I then changed the classes that needed the new enum to Implement Interface B instead of Interface A since it was Inherited by Interface B. I thought about Implementing both Interfaces in my classes that needed them but I'm using the Interface throughout the code and would like to just use one Interface for looking through classes and not two.

我似乎无法找到答案,只想确保它是一个不错的编码标准。我有许多不同的类使用的接口 A,不希望接口 A 改变。我遇到了一个新需求,它要求实现接口 A 的许多类都需要一个枚举,但并非所有类都需要这个枚举。我不希望不需要这个新枚举的类来实现这个新功能。所以我创建了包含我需要添加的新枚举的接口 B。然后我让接口 B 继承接口 A,这是我关心的问题,一个接口可以继承另一个接口吗?为了继续我的更改,我将需要新枚举的类更改为实现接口 B 而不是接口 A,因为它是由接口 B 继承的。

I hope this was clear enough (probably to long) but if anyone can give me some advice on this either I'm doing it right or I'm doing it wrong please let me know.

我希望这足够清楚(可能很长)但是如果有人可以就此给我一些建议,要么我做对了,要么做错了,请告诉我。

Thanks!

谢谢!

回答by Jeff Sternal

Interface inheritance is an excellent tool, though you should only use it when interface B is truly substitutable for interface A, not just to aggregate loosely-related behaviors.

接口继承是一个很好的工具,尽管你应该只在接口 B 真正可以替代接口 A 时使用它,而不仅仅是聚合松散相关的行为。

It's difficult to tell whether it is appropriate for your specific case, but there's nothing wrong using the practice in principle. You see it in the first-rate APIs all the time. To pick just one common example, from the .NET framework:

很难判断它是否适合您的具体情况,但原则上使用这种做法没有错。您一直在一流的 API 中看到它。仅从 .NET 框架中选取一个常见示例:

public interface ICollection<T> : IEnumerable<T>, IEnumerable

回答by mark_h

Consider whether the interfaces should be logically paired, and if you feel that they work well with each other then absolutely use inheritance.

考虑接口是否应该在逻辑上配对,如果你觉得它们可以很好地相互配合,那么绝对使用继承。

Lets look at an example;

让我们看一个例子;

public interface IScanner
{
    void Scan();
}

public interface IPrinter
{
    void Print();
}

Printers and scanners are often separate objects, each with their own functionality however these two devices are often paired in the same device;

打印机和扫描仪通常是独立的对象,每个都有自己的功能,但这两个设备通常在同一设备中配对;

public interface IPhotocopier : IScanner, IPrinter
{
    void Copy();
}

It makes sense that IPhotocopier should inherit from IScanner and IPrinter as this now allows the photocopier to be used as either a scanner or printer (which it contains) in addition to its primary roll as a copier.

IPhotocopier 应该从 IScanner 和 IPrinter 继承是有道理的,因为这现在允许复印机除了用作复印机的主要卷筒外,还可以用作扫描仪或打印机(它包含)。

Now lets look at one more interface;

现在让我们再看一个界面;

public interface IBlender
{
    void Blend();
}

It would not make sense to allow IBlender to be inherited by any of the earlier interfaces (what would you call them? IBlendingScanner?).

允许任何早期的接口继承 IBlender 是没有意义的(你怎么称呼它们?IBlendingScanner?)。

If you can't give your new interface a sensible name this might indicate that your may not want to use inheritance in this instance.

如果你不能给你的新接口一个合理的名字,这可能表明你可能不想在这个实例中使用继承。

It's a bad idea to inherit some interfaces such as IDisposable, since this forces all implementations of your new interface to implement the dispose pattern even if they do not have any disposable resources.

继承一些接口(例如 IDisposable)是一个坏主意,因为这会强制新接口的所有实现都实现处置模式,即使它们没有任何可支配资源。

回答by Joel Mueller

Technically speaking, interfaces don't inherit from each other. What really happens when you create an IFoothat inherits from IBar, you're saying that any class that implements IFoomust also implement IBar.

从技术上讲,接口不会相互继承。当您创建一个IFoo继承自 的 时IBar,实际上会发生什么,您是说任何实现的类也IFoo必须实现IBar

interface IBar
{
    void DoBar();
}

interface IFoo : IBar
{
    void DoFoo();
}

In this example, the IFoointerface does not have a DoBar()method. Most of the time the distinction doesn't matter, but it can bite you when using reflection on an interface rather than a class.

在这个例子中,IFoo接口没有DoBar()方法。大多数情况下,区别并不重要,但是当在接口而不是类上使用反射时,它会咬你。

回答by qid

It is certainly possible to have an inheritance tree of interfaces, and even "multiple inheritance" with interfaces. Whether it is the right thing to do or not depends on the interfaces in question. If it really is the case that interface B is an extension or refinement of interface A, then inheritance makes sense, but if the new enum is largely unrelated to the concept expressed by interface A, I would make them two separate interfaces and have the classes that need to implement both interfaces.

当然可以有接口的继承树,甚至可以有接口的“多重继承”。这样做是否正确取决于所讨论的接口。如果接口 B 确实是接口 A 的扩展或改进,那么继承是有意义的,但如果新枚举与接口 A 表达的概念在很大程度上无关,我会将它们设为两个单独的接口并具有类需要实现两个接口。

回答by J. Loomis

IMO this is exactly the right approach, I don't see any problem with it.

IMO 这正是正确的方法,我认为没有任何问题。

回答by Despertar

I think databases always provide a great way to demonstrate interfaces, so considering if an interface should inherit another interface look at the following,

我认为数据库总是提供一种很好的方式来演示接口,因此考虑一个接口是否应该继承另一个接口,请看以下内容,

IMySqlDatabase : IDatabase
MySqlDatabase : IMySqlDatabase

IMsSqlDatabase : IDatabase
MsSqlDatabase : IMsSqlDatabase

A MySqlDatabase IS an IMySqlDatabase and an IMySqlDatabase IS an IDatabase.

MySqlDatabase 是一个 IMySqlDatabase,一个 IMySqlDatabase 是一个 IDatabase。

Now if you need to make changes to your IDatabase interface it's grandchildren (the conrete database classes) can reap the benefits, but you won't have to expand MySQL AND MsSQL (or perhaps even more DBMS' Interfaces). At the same time in your middle man (IMsSqlDatabase) you can still have interface features that a MySQL or Oracle DB wouldn't support.

现在,如果您需要更改您的 IDatabase 接口,它的子孙(conrete 数据库类)可以获得好处,但您不必扩展 MySQL AND MsSQL(或者甚至更多 DBMS 的接口)。同时,在您的中间人 (IMsSqlDatabase) 中,您仍然可以拥有 MySQL 或 Oracle DB 不支持的接口功能。