大多数时候,当在决定是否应该使用接口或抽象类之间进行讨论时,最终会定义如何使用它们,但并不总是为什么以及何时使用它们?此外,您最终可能也会使用的其他明显的具体类和实用程序类并不总是被提出。真的,在我看来,回答这个问题的正确方法是确定你正在处理的关于域或实体对象的上下文,即你的用例是什么?
从一个非常高的层次来看,Java 由使用方法相互通信的对象(可以对现实世界中的对象建模的实体或领域对象)组成。无论如何,您希望使用接口对行为进行建模,并在继承时使用抽象类。
我使用自上而下然后自下而上的方法来执行此操作。我开始通过查看用例并查看我需要哪些类来寻找继承。然后我看看是否有一个包含所有对象的 superClassOrInterfaceType(因为类和接口都定义了类型,为了简单起见,我将它们组合成一个词。希望它不会让它更混乱)域对象,如果我正在处理处理 subtypeClassOrInterfaceTypes 的用例,例如车辆的 superClassOrInterfaceType,例如:汽车、卡车、吉普车和摩托车。如果有层次关系,那么我定义了superClassOrInterfaceType和subtypeClassOrInterfaceTypes。
正如我所说,我通常首先要做的是为我正在处理的对象寻找一个公共域 superClassOrInterfaceType。如果是这样,我在 subtypeClassOrInterfaceTypes 之间寻找公共方法操作。如果没有,我看看是否有通用方法实现,因为即使您可能有一个 superClassOrInterfaceType 并且可能有通用方法,这些实现可能不利于代码重用。在这一点上,如果我有通用方法,但没有通用实现,我倾向于接口。但是,通过这个简单的示例,我应该在车辆子类型ClassOrInterfaceTypes 之间有一些通用方法和一些通用实现,我可以重用代码。
另一方面,如果没有继承结构,那我从下往上开始,看看有没有常用的方法。如果没有通用的方法,也没有通用的实现,那我选择具体的类。
一般来说,如果有通用方法和通用实现的继承,并且在同一个子类型中需要多个子类型实现方法,那么我会选择一个抽象类,这很少见,但我确实使用它。如果只是因为继承而使用抽象类,那么如果代码更改很多,您可能会遇到问题。这在此处的示例中非常详细:Interfaces vs Abstract Classes in Java,用于不同类型的电机域对象。其中一个需要双动力电机,这需要在单个子类型类中使用多种子类型实现方法。
总而言之,作为一条规则,您希望使用接口而不是抽象类来定义行为(对象将做什么)。抽象类专注于实现层次结构和代码重用。
这里有一些更详细的链接。
Thanks Type & Gentle Class
The Magic behind Subtype Polymorphism
Maximize Flexibility with Interfaces & Abstract Classes
Interfaces vs Abstract Classes in Java