我应该直接实现接口还是让超类来实现?


14

两者之间有区别吗

public class A extends AbstractB implements C
{...}

与...

public class A extends AbstractB
{...}
abstract class AbstractB implements C
{...}

我知道在两种情况下,类A最终都将符合该接口。在第二种情况下,AbstractB可以在中提供接口方法的实现C。那是唯一的区别吗?

如果我不想提供任何的接口方法的实现 AbstractB我应该使用哪种风格?使用一个或另一个具有隐藏的“文档”目的吗?


3
关于标题的建议:我应该直接实现接口还是让超类来实现
Jeanne Boyarsky 2012年

Answers:


20

这完全取决于是否在AbstractB implements C语义上。即,如果在语义AbstractB上实现有意义C,那么就去实现它。

如果我们举一些具体的例子,语义上的区别就很明显了。

如果A =狗,AbstractB =动物,C = IBark

唯一有意义的选择是

class Dog extends Animal implements IBark{

这没有任何意义,因为这意味着所有动物都会吠叫。

class Animal implements IBark{

如果您不仅仅class A继承自,其他差异也会发挥作用AbstractB。在#1中,他们不需要实现C;在#2中,它们都被迫实现C。


1
+1比我的答案还清晰!
Hand-E-Food

另外,如果接口是Heterotroph合理的,则可以Animal实现Implement Heterotroph。如果您希望有很多其他的吠叫动物,并且希望以同样的方式对待它们,BarkingAnimal extends Animal implements IBark那么您可以走另一类。
围巾岭12/12/19

@scarfridge实际上,我希望动物能够继续生活,Heterotroph但是感谢您的投入
Karthik T

2

确定适当的继承关系的简单方法不是查看类本身,而是查看调用这些类中的方法的代码。在代码中的某处,您有类似AbstractB b = new A();或的东西otherObject.addAbstractB(this);。无论哪种方式,您以后都可以使用该AbstractB引用进行各种方法调用。

在这种情况下,您是否要调用方法C?如果是这样,AbstractB则应实施C。如果没有,那就不应该。如果您没有类似的情况,那么您就不需要继承,而应该重构使用合成,因为它的耦合度要低得多。


2

这不是“隐藏”文档目的。它允许您将AbstractB及其所有子类转换为C。实际上有三种样式。

public class A extends AbstractB implements C
public class AbstractB

如果AbstractB没有在逻辑上实现C,我将使用这一代码。即使它不提供方法,它也可能具有一定的意义。如狗伸动物器皿。对于所有动物来说,摇动并不是没有道理的。注意,这种方法实际上并没有阻止AbstractB提供实现。

public class A extends AbstractB
public AbstractB implements C

如果我希望所有子类都实现该接口,并且对所有子类都这样做是有意义的,那么我将使用该子类。例如Beagle扩展AbstractDog工具Wag。

public class A extends AbstractB implements C
public class AbstractB implements C

这是多余的,但可能会增加清晰度。


我认为第二段中的“ AbstractC”(问题中不存在)应更改为“ AbstractB”。我无法进行编辑,因为编辑者必须至少包含6个字符。
cellepo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.