Java中接口扩展接口的优化

4

我有一个接口A,包含两个方法:

public interface A{
    method One();
    method Two();
}

And I have two options for interface B:

Case 1:

public interface B{
    method One();
    method Two();
    method Three();
}

案例二:

public interface B extends A{
    method Three();
}

有人能告诉我上述两种情况哪种更好实施,以及为什么吗? Case 2有哪些缺点?

编辑:在接口B中,我需要接口A的两种方法。所以,我认为扩展会更好。 有些类只需要方法一和方法二,那么我会实现接口A。而需要方法一、二和三时,我就会实现接口B。


4
你应该做你认为最清晰简单的事情。 - Peter Lawrey
对我来说,情况2更清晰,我只是在想使用情况2是否有任何不利因素? - OnePunchMan
@kaze 我同意,案例2的唯一缺点是你不能在B中给方法不同的javadoc。以Collection和Set为例。如果你没有这个要求,我不会试图做到DRY(不要重复自己),而不是WET(写两遍)。 - Peter Lawrey
1
@kaze 抱歉,我的意思是我试图成为DRY而不是WET。 - Peter Lawrey
@PeterLawrey 感谢您的提示! - OnePunchMan
6个回答

4

这取决于您的逻辑。考虑以下两对接口:

interface House {
    int doorCount();
    int windowCount();
}

interface Automobile {
    int doorCount();
    int windowCount();
    int wheelCount();
}

如果有人试图通过将房子加上轮子来制造汽车,那么他一定是失去了理智。因为汽车不是带轮子的房子。

然而,在这种情况下,

interface House {
    int doorCount();
    int windowCount();
}

int Mansion extends House {
    int poolCount();
}

House派生出Mansion是有意义的,因为Mansion是具有“附加功能”的House的一种。


所以,在“豪宅扩展房屋”的情况下没有任何不利影响。 - OnePunchMan
@kaze 正确,只有好处:您可以编写处理“House”接口的代码,而不必考虑某些房屋是豪宅。 - Sergey Kalinichenko

4
这取决于您需要做什么。如果 method Three() 引入的功能从设计角度来看应该封装到另一个单元(如接口或类)中,则使用 2;如果它是类似的功能,则使用 1。
编辑: 还有一种选择:接口不必互相扩展,具体类可以实现它们两个,但同样取决于您需要做什么。
编辑2: 在您的编辑之后,仍然没有太大的区别。仍然可以使用多态赋值在两个类上。例如,如果 class concreteA implements interfaceAclas concreteB implements interfaceB 或者 class concreteB implements interfaceA,interfaceB,您仍然可以使用 InterfaceA classB = new concreteB();

1
如果您选择方案1,并且已经编写了针对类型A的客户端代码,则该代码在与实现B的类的实例一起使用时将无法正常工作,这纯粹是由于行政程序原因:B在概念上是A的扩展,但在Java类型系统中被建模为不同的类型。
例如:
static void existingMethod(A a) {
  ...work with a ...
}

class ImplB implements B { ... }

public static void main(String... args) {
   B b = new B();
   existingMethod(b); // compile error for Case 1; Case 2 compiles fine.
}

因此,让你的 B 类型扩展 A 类型会更有意义。

我已经检查过了。您希望我在添加的文本中注意到什么? - Marko Topolnik

1

一种方法是看 AB 之间的关系类型。

如果 B "是一个" A,那么选择第二种情况更有意义。


1

这取决于你使用接口的目的。如果所有使用接口A的接口也使用接口B,那么你可以使用方案1并完全摒弃接口A。否则,没有理由重复代码。复制代码意味着如果你改变了某些内容,你必须到处更改,而不是只在一个地方更改。


在这种情况下,我会使用第二种方法,因为它减少了代码重复。 - DonyorM

1
如果您拥有A并想使用它,则可以选择B扩展A。如果只是因为重用方法声明而将B从A扩展,则您的具体类必须实现所有3个方法,这是一个缺点(没有太多用处),尤其当您只关注B时。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接