1. 如果你只是想要多种实现以进行设计并且需要在开发期间编写代码,那么接口是我们最好的选择。 2. 如果你想要重用代码,那么我们可能会使用抽象类。
然而,我看到了一些既非接口又非抽象类的情况。
在某些设计中,它像这样:接口 > 基类 > 子类。
因此,基类实现了所有方法,然后子类从中继承定义。为什么我们不能使用抽象类代替这种设置?或者说这是一个有缺陷的设置吗?
最简单的推理是,如果一个对象具有IS-A关系,则使用(抽象)基类。例如,马是一种动物。
如果存在CAN关系,则考虑使用接口,例如如果一只鸭子可以飞,可以为其使用IFlying作为能够飞行的鸭子的接口。
接口可以用于将多个接口实现到一个类中。在C#中,你不能从多个类派生。
这是一种设计和个人品味的问题,通常当你声明一个接口时,你并不真正关心具体的实现方式,而只关心接口应该提供的封装功能。
拥有抽象类确实定义了一些指定的行为,但这并不总是你想要的。
同时,拥有抽象类会禁止你继承多个类,因此会限制它可以拥有的功能。
在设计类层次结构时,你会问自己“在这种情况下应该使用什么对象?”并为该功能定义一个接口,然后,在提供实现时,你可以意识到某些功能应该被分组并重复使用于某些子类中,但这是随后才会发生的。
接口实际上是功能的一种契约,指定了某些方法和属性。可针对该接口编写代码段,而不需要任何实现细节的知识。
抽象类可能实现一些接口,但也可能包含所有派生类型都可能需要的一些公共功能。它还可以包括抽象或虚拟方法/属性,允许派生类型自定义部分功能。
考虑这样一种情况:您构建了一些对象模型,并使用接口定义该模型的结构,但您希望允许代码的使用者在不影响核心设计的情况下编写自己的实现。然后您可以为一个实现构建自己的基类。派生类型将继承此基类,而此基类又实现了对象模型的接口。接着其他人可能会编写自己的实现,但想要与您现有的实现具有不同的功能或行为。因此,他们编写自己的基类以及扩展其自己的派生类型。
按照这种方案,没有真正的理由不能同时使用抽象类和接口。这完全取决于您的目的以及如何构建您的代码。
接口定义了一组属性和功能,类必须实现并可以由任意数量的类实现。基类也可以实现接口。例如,许多不同的基类可能使用IComparable接口。
接口的主要规则如下: