Java 为什么父类和子类都实现相同的接口?

Java 为什么父类和子类都实现相同的接口?,java,inheritance,interface,Java,Inheritance,Interface,我继承了一些遗留Java(1.4)代码,这个设计决策经常出现。我不明白这有什么目的或理由 public interface SoapFacade extends iConfigurable{ } public class SoapFacadeBase implements SoapFacade{ ... } public class SoapFacadeImpl extends SoapFacadeBase implements SoapFacade{ ... } 正如我对接口的理解(我的

我继承了一些遗留Java(1.4)代码,这个设计决策经常出现。我不明白这有什么目的或理由

public interface SoapFacade extends iConfigurable{ }

public class SoapFacadeBase implements SoapFacade{
...
}

public class SoapFacadeImpl extends SoapFacadeBase implements SoapFacade{
...
}
正如我对接口的理解(我的实验也加强了这一点),让父级和子级实现相同的接口是没有意义的。在此场景中,从
SoapFacadeBase
SoapFacadeBase
的所有内容都在
SoapFacadeBase
中实现,但是
iconfiguable
中的方法在
soapfacadempl
中实现。但是,这并不需要使用
soapfacadeinpl
实现
SoapFacade


关于接口,是否有什么我不知道的东西可以给这个模式带来一些用途或好处?除了缺乏清晰性之外,还有哪些潜在的成本可以驱动重构吗?或者,为了清晰/简单起见,应该对其进行重构吗?

如果您也将该接口用作标记<代码>类.getInterfaces()将仅返回直接实例化的接口

根据我对接口的理解(我的实验也加强了这一点),让父级和子级实现相同的接口是没有意义的。

不。从技术上讲,这是完全多余的

但是,它确实记录了这样一个事实,即您打算将
soapfacadeinpl
作为
SoapFacade
,并且如果您(或其他人)决定从基类中删除
implements SoapFacade
,它会确保您得到编译错误


在标准Java集合API中随处可见这种模式
ArrayList
实现了
List
,即使它的基类(
AbstractList
)已经实现了。对于
HashSet
/
AbstractSet
Set
接口也是如此。

我实际上发现这种设计毫无意义。如您所述,实现的接口只是继承的,因此无需在子类上复制和粘贴“implements SomeInterface”。
它不是更清晰、更聪明,或者其他什么…

这是胡说八道,不要这样做


尤其是在像java集合这样的公共API中。这完全是胡说八道。

它有一些副作用。如果你想用soapthingelse替换SoapFacade(不是重命名SoapFacade,而是用一个完全不同的接口替换),你必须到处替换它,而且一些ide的“重构”特性(比如Eclipse)也帮不了你。而且,如果你把代码传递给其他人,他们可能会花上几分钟来找出他们在子类(比如:wtf…这是谁写的)+1上出现编译错误的原因,这确实给了我一些其他的思考。从发布的示例来看,
SoapFacade
中的所有内容都在基类中实现;因此,我更倾向于从派生类中删除
implements SoapFacade
,以便从子类中隐藏
SoapFacade
的细节。@Giacormo,你说的“在子类上获取编译错误”是什么意思?它确实保证子类实现接口,即使基类被重构并且不再实现接口。它还用于文档编制。还应该注意的是,它在标准集合API中几乎无处不在。看看我的答案。