我应该何时使用接口,何时使用基类?

如果我不想实际定义方法的基本实现,它应该始终是一个接口吗?

如果我有狗和猫的课。为什么我要实现IPet而不是PetBase?我可以理解为ISheds或IBarks(IMakesNoise?)提供接口,因为它们可以逐个宠物放置,但我不知道该为普通宠物使用哪个接口。


当前回答

接口和基类表示两种不同形式的关系。

继承(基类)表示“is-a”关系。例如,狗或猫是宠物。这种关系始终代表着班级的(单一)目的(结合“单一责任原则”)。

另一方面,接口表示类的其他特性。我将其称为“是”关系,如“Foo是一次性的”,因此C#中的IDisposable接口。

其他回答

下面是接口和基类的基本和简单定义:

基类=对象继承。接口=功能继承。

干杯

一个重要的区别是,只能继承一个基类,但可以实现多个接口。因此,如果您绝对确定不需要同时继承不同的基类,那么只需要使用基类。此外,如果你发现你的接口越来越大,那么你应该开始把它分成几个逻辑块来定义独立的功能,因为没有规则规定你的类不能实现所有的功能(或者你可以定义一个不同的接口来继承所有的功能)。

接口

大多数语言允许您实现多个接口修改接口是一项突破性的更改。所有实现都需要重新编译/修改。所有成员都是公共的。实现必须实现所有成员。接口有助于解耦。您可以使用模拟框架模拟接口后面的任何内容接口通常表示一种行为接口实现彼此分离/隔离

基类

允许您添加一些通过派生免费获得的默认实现(从C#8.0通过接口可以获得默认实现)除了C++,您只能从一个类派生。即使可以从多个类中选择,这通常也是一个坏主意。更改基类相对容易。派生不需要做任何特殊的事情基类可以声明可由派生访问的受保护函数和公共函数抽象基类不能像接口那样容易被模仿基类通常表示类型层次结构(IS A)类派生可能会依赖于一些基本行为(具有复杂的父实现知识)。如果你对一个人的基本实现进行更改并打破其他人,事情可能会很混乱。

如果除了您的类型成员之外,其他开发人员确实没有任何理由希望使用自己的基类,并且您预见到版本控制问题,那么您应该使用基类(请参见http://haacked.com/archive/2008/02/21/versioning-issues-with-abstract-base-classes-and-interfaces.aspx).

如果继承开发人员有任何理由使用自己的基类来实现类型的接口,并且您没有看到接口发生变化,那么就使用接口。在这种情况下,为了方便起见,您仍然可以加入实现接口的默认基类。

关于C#,在某些意义上,接口和抽象类可以互换。然而,区别在于:i)接口不能实现代码;ii)由于这一点,接口不能进一步调用堆栈上的子类;以及iii)抽象类只能在类上继承,而多个接口可以在类上实现。