当有多个派生类共享相同的抽象行为时,您该怎么办?
以.NET中的Stream
类为例,这是一个很好的例子。
我一直将抽象类作为派生类的路线图。很多时候,我会有一系列相似的类,它们都能共享功能,但又各自不同,需要拥有自己的类。因此,基类并不完全功能化,它有一些方法是为了那个特定的类而设计的。因此,通过声明它为抽象类,您可以将功能放入命名空间以供通用使用,但仍然可以将其使用限制在该类集合中。
接口(对我来说)只是一个蓝图。我从未需要过接口,但在发布可扩展API或在组织内部制作框架时,接口是描述可扩展类应如何行事的良好蓝图。它有助于定义命名空间中特定对象所期望的功能标准。
我认为两者都不是必需的,但它们在隔离代码和定义如何使用和/或扩展代码方面非常有帮助。
接口意味着您可以定义类应该实现但实际上没有实现的方法。为什么这很有用的一个例子是允许开发人员为您的应用程序编写插件。
必须清楚地知道可以在此插件上调用哪些方法(例如load、unload execute等),但这些方法的实现方式取决于插件本身。在设计接口时,您可能不知道这些方法的代码实际上是什么。
至于抽象类,虽然相似,但通常用作类似类的基础。在Stream基类的情况下,它具有读取一块字节的方法,它可以通过重复调用方法来调用单个字节。如果您有几个从此基类派生的类,则不必在每个类中重复此代码;因此,通常使用抽象类来减少代码重复。
简单来说,您可以使用抽象类来模拟继承,例如汽车从车辆继承。通常,您还将继承一些实现或类定义。
接口用于建模可能具有类似行为子集但不一定是is-a关系的类型。例如,我可以有一个名为IValidate的接口,其中包含一个Validate方法,可以由Car、Student、Account等实现以验证它们所持有的数据。这些类型不能/不应该真正被建模为is-a关系
接口也广泛用于不支持多重继承的语言中作为解决方法。其他用途包括依赖项分离和在COM和WCF中公开服务。