实现具有相同方法的多个接口

这段代码完美无缺。 方法test()适用于两个接口。 引擎盖下究竟发生了什么? 这个function在实际场景中有用吗?

interface A { void test(); } interface B { void test(); } class C implements A, B { public void test() { System.out.println("abc"); } } A a = new C(); a.test(); B b = new C(); b.test(); 

因为它是一个界面,所以没有任何伤害。 您基本上通过实现AB为您的C类使用蓝图。 AB都说C应该实现一个名为test()的方法

您的C类实现了该方法,因此接口已完成其工作。

它基本上是你的C类说:“哦,嘿,我需要实现test()因为接口A ”并且你实现它。 然后你的C类说“哦,嘿,我需要再次实现test() ,因为接口B ”并且它看到已经有一个名为test()的方法已经实现,所以它很满意。

您还可以在此处找到更多信息: JLS§8.4.8.4

JLS§8.4.8.4说,

使用覆盖等效签名inheritance方法

一个类可以使用覆盖等效签名inheritance多个方法(第8.4.2节)

可能有几个路径可以从接口inheritance相同的方法声明。 这个事实没有任何困难,从来没有导致编译时错误。

似乎理由是如果一个类具有多个具有相同名称和签名的声明,因为该类可能通过多个路径inheritance它们 – 实现接口并且还子类化实现该接口的类,例如 – 没有损害。

假设我们有两个接口……

 public interface StockBroker{ //Give our client some investment strategies. public String adviseClient(Client c); } public interface Doctor{ //Examine our client and give them some medical advice public String adviseClient(Client c); } 

一个实现两个接口的类….

 public class JackOfAllTrades implements StockBroker, Doctor{ public String adviseClient(Client c){ } } 

虽然使用一种方法实现两个接口在语法上可能是正确的,但您可能无法获得所需的行为。 例如,股票经纪人和医生通常都会给客户提供截然不同的建议。

有人使用实现接口的对象Doctor希望adviseClient()方法提供医疗建议。 但是有人使用实现接口StockBroker的对象期望adviseClient()方法提供投资策略。

在这种情况下,对象JackOfAllTrades不知道要提供什么类型的建议,因为adviseClient()方法没有参数告诉它在adviseClient()时它应该实现哪个接口。

这是Java的一个缺点,因为设计Doctor界面的人可能无法知道其他人会使用相同的方法签名设计StockBroker界面。

对于任何创建接口的人来说,最好的做法是使方法名称足够独特,名称冲突很少见。

就语法而言,如果没有遵守其中一个methodsintent ,它的合同就会被破坏, 代码可能会被视为破坏

用你的比喻,如果我答应迈克尔穿蓝色衬衫而不是红色衬衫,我不能穿两件衬衫,那么我将不得不打破至少一个承诺。

对于这些方法也是如此:如果保持一个合同意味着打破另一个,那么implement两个interfaces实际上是一个坏主意。

编辑 :合同损坏,按照Class C signature它应该实现两个方法,但最终它只实现一个method而省略另一个method

参考

 interface A { void test(); } interface B { void test(); } class C implements A, B { public void test() { System.out.println("common to all"); } public A choose(A a){ return new A(){ public void test() { System.out.println("test of A"); } }; } public B choose(B b){ return new B(){ public void test() { System.out.println("test of B"); } }; } } class Demo { public static void main(String[] args) { C c =new C(); A a = new C(); B b = new B(); a = c.choose(a); b = c.choose(b); a.test(); b.test(); } }