2013-07-05 131 views
11

此代码完美工作。 test()方法适用于这两个接口。发动机罩下面究竟发生了什么?这个功能在实际场景中如何有用?实现多个具有相同方法的接口

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(); 
+0

[Java抽象类实现接口的可能重复,都有相同的方法](http://stackoverflow.com/questions/15202185/java-abstract-class-implements-an-interface-both-have-the -same-method) –

+0

请不要重复关于抽象类和接口,它与两个接口基本相同。 –

+0

可能的重复[在一个类中实现2个接口,方法相同。哪个接口方法被覆盖?](http://stackoverflow.com/questions/2801878/implemeting-2-interfaces-in-a-class-with-same -method-which-interface-method-is-o) – adatapost

回答

12

因为它的接口也没有做过伤害。通过实施AB,您基本上正在为您的C课程使用蓝图。无论ABC应实施一个名为test()

C类的方法实现了该方法,所以接口都做他们的工作。

它基本上是你的C类说:“哦,嘿,我需要执行test()因为接口A”,你实现它。然后你的C类说:“哦,嘿,我需要再次实施test(),因为接口B”,它看到已经有一种方法称为test()实现,因此它满意。

你也可以在这里找到更多的信息:JLS §8.4.8.4

1

不就语法而言,但如果methods之一的intent不遵守,其合同被打破,代码可以被视为打破

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

同样可以容纳的方法:如果保留一份合同意味着打破其他合同,那么它实际上是一个坏主意implement两个interfaces

编辑:合同破碎,按照Class C signature应该实现两个方法,但最终它只是一个method实施并忽略其他。

Reference

+0

你能解释一下**合约在哪里以及如何破碎吗? – NINCOMPOOP

+0

合同破裂,按照C类签名它应该实现两种方法,但最终只能实现一种方法而忽略另一种方法。 –

+3

*它应该实现两种方法* ???它应该实现一个声明为void test()的方法,第二个是哪里? – NINCOMPOOP

6

JLS §8.4.8.4说,

与覆盖等效签名

这是可能的类继承与多种方法继承的方法超驰等效签名(§8.4.2)
...
There可能是几个路径,通过这些路径可以从接口继承相同的方法声明。这一事实不会造成任何困难,而且本身也不会导致编译时错误。

看来理由是,如果一个类具有相同的名称和签名多个声明,因为类可能已经通过多个继承了他们的路径,实现一个接口,也继承实现该接口的类,对例如 - 没有伤害完成。

+0

如果方法的返回类型在两个接口中不同,该怎么办? –

+0

@premktiw编译错误。 JLS中的关键词是*覆盖等效签名*。在覆盖中更改返回类型是不合法的。 – andrewdotn

2
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(); 
    } 
} 
+4

没有解释的代码不是答案 – BrDaHa

5

假设我们有两个接口...

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的一个缺点,因为设计接口的人可能无法知道别人会用相同的方法签名来设计一个接口StockBroker

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

相关问题