如何在抽象class和接口之间进行选择

How to choose between abstract class and interface

我有一段时间没有做 OOP 所以我有点生疏。 例如,我有一个租用订阅的客户,它存在 3 种类型的订阅。我如何为我的 "Subscription" class 选择抽象 class 和接口?

每个订阅必须有价格、最长租借期限和最大租借次数。

据我所知,我会在这里使用接口,但我如何强制其他 class 实现订阅的实体指定这 3 个属性的值(常量)?

我认为在这种情况下摘要 class 更有意义。当您的 classes 都处理相同的 data/methods 但在方法逻辑上可能略有不同时,请使用抽象 classes。

当您有多个 class 有很大差异但应始终受限于一组方法(接口方法)的接口时,接口可能会更有用

通常在继承和多态的情况下使用抽象。当您有一个对象可以根据其内部类型具有不同的行为时。当需要合同时使用接口。一般来说,抽象最适合密切相关的对象,而选择接口是为了它们的功能。

在你的情况下抽象是有道理的。您可以在基础 class 中保留互属性并从中派生其他 classes。消除了一些冗余代码。

这里是 MS suggested:Here 的一些建议,可帮助您决定是使用接口还是抽象 class 来为您的组件提供多态性。

*如果您希望创建组件的多个版本,请创建一个摘要 class。 Abstract classes 提供了一种对组件进行版本控制的简单易行的方法。通过更新基础 class,所有继承的 classes 都会随着更改自动更新。另一方面,接口一旦创建就不能更改。如果需要新版本的界面,您必须创建一个全新的界面。

*如果您创建的功能将对广泛的不同对象有用,请使用接口。抽象 classes 应该主要用于密切相关的对象,而接口最适合为不相关的 classes 提供通用功能。

*如果您设计的是小而简洁的功能,请使用界面。如果您正在设计大型功能单元,请使用抽象 class.

*如果您想在组件的所有实现中提供通用的、已实现的功能,请使用抽象 class。抽象 classes 允许您部分实现 class,而接口不包含任何成员的实现。

https://msdn.microsoft.com/en-us/library/scsyfw1d(v=vs.71).aspx

如果您正在考虑定义对所有实现都通用的字段,则不能使用接口,因为接口不包含状态。它可以只声明方法和常量。状态被视为实现的一部分,而不是类型信息。

但是,您可以定义三个抽象的 getter 方法 - getPrice()getDuration()getCount() 或类似的方法,然后将这些方法的实际实现留给致力于实施 classes。在这种情况下,您可以使用接口或抽象 class.

如果您有一些实现是所有子class 通用的,您会选择抽象class。例如,如果您有特定的方式来执行 "rent out" 或 "send reminder to renter" 或其他操作。这些方法将是具体的,只有上述三个 getter 是抽象的。

如果您没有任何常用操作,并且发现自己只有抽象方法而没有其他任何东西,那么接口可能最适合您,尤其是因为 Java 是单继承,并且使用接口将允许您在创建具体 classes 时扩展另一个 class。

不过,这些只是经验法则,并非一成不变的规则。