简体   繁体   English

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

[英]Implementing multiple interfaces having same method

This code works perfectly. 这段代码完美无缺。 The method test() works for both interfaces. 方法test()适用于两个接口。 What is exactly going on under the hood? 引擎盖下究竟发生了什么? And how is this feature useful in practical scenario? 这个功能在实际场景中有用吗?

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

Because it's an interface there is no harm done. 因为它是一个界面,所以没有任何伤害。 You're basically using a blueprint for your C class by implementing A and B . 您基本上通过实现AB为您的C类使用蓝图。 Both A and B say that C should implement a method called test() AB都说C应该实现一个名为test()的方法

Your C class implements that method, so the interfaces have done their job. 您的C类实现了该方法,因此接口已完成其工作。

It's basically your C class saying: "Oh hey, I need to implement test() because of interface A " and you implement it. 它基本上是你的C类说:“哦,嘿,我需要实现test()因为接口A ”并且你实现它。 Then your C class says "Oh hey, I need to implement test() again because of interface B " and it sees that there is already a method called test() implemented so it's satisfied. 然后你的C类说“哦,嘿,我需要再次实现test() ,因为接口B ”并且它看到已经有一个名为test()的方法已经实现,所以它很满意。

You can also find more information here: JLS §8.4.8.4 您还可以在此处找到更多信息: JLS§8.4.8.4

JLS §8.4.8.4 says, JLS§8.4.8.4说,

Inheriting Methods with Override-Equivalent Signatures 使用覆盖等效签名继承方法

It is possible for a class to inherit multiple methods with override-equivalent signatures (§8.4.2) 类可以使用覆盖等效签名继承多个方法(第8.4.2节)
...
There might be several paths by which the same method declaration might be inherited from an interface. 可能有几个路径可以从接口继承相同的方法声明。 This fact causes no difficulty and never, of itself, results in a compile-time error. 这个事实没有任何困难,从来没有导致编译时错误。

It seems the rationale was that if a class has multiple declarations with the same name and signature, since the class may have inherited them through multiple paths—implementing an interface and also subclassing a class that implements that interface, for example—no harm is done. 似乎理由是如果一个类具有多个具有相同名称和签名的声明,因为该类可能通过多个路径继承它们 - 实现接口并且还子类化实现该接口的类,例如 - 不会造成伤害。

Suppose we have two interfaces... 假设我们有两个接口......

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);
}

And a class implementing both interfaces.... 并且实现两个接口的类....

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

While it may be syntactically correct to implement both interfaces with one method, you may not get the desired behavior. 虽然使用一种方法实现两个接口在语法上可能是正确的,但您可能无法获得所需的行为。 For example, a stock broker and a doctor typically each give their clients vastly different advice. 例如,股票经纪人和医生通常都会给客户提供截然不同的建议。

Someone using an object that implements the interface Doctor expects the adviseClient() method to give medical advice. 有人使用实现接口的对象Doctor希望adviseClient()方法提供医疗建议。 But someone using an object that implements the interface StockBroker expects the adviseClient() method to give out investment strategies. 但是有人使用实现接口StockBroker的对象期望adviseClient()方法提供投资策略。

In this case, the object JackOfAllTrades does not know what type of advice to give out because the adviseClient() method has no parameters telling it which interface it is supposed to be implementing when adviseClient() is called. 在这种情况下,对象JackOfAllTrades不知道要提供什么类型的建议,因为adviseClient()方法没有参数告诉它在adviseClient()时它应该实现哪个接口。

This is a shortcoming in Java because the person designing the Doctor interface may have had no way of knowing that someone else would design a StockBroker interface with the same method signature. 这是Java的一个缺点,因为设计Doctor界面的人可能无法知道其他人会设计具有相同方法签名的StockBroker界面。

To anyone creating interfaces, its probably good practice to make the method names unique enough that name collisions are rare. 对于任何创建接口的人来说,最好的方法是使方法名称足够独特,名称冲突很少见。

Not as far as syntax is concerned but if the intent of one of the methods is not adhered to, its contract is broken and the code can be considered as broken . 就语法而言,如果不遵守其中一种methodsintent ,则其合同将被破坏, 代码可被视为已损坏

Using your analogy, if I promised Michael to wear a blue shirt instead of a red shirt, and I can't wear two shirts, then I will have to break at least one promise. 用你的比喻,如果我答应迈克尔穿蓝色衬衫而不是红色衬衫,我不能穿两件衬衫,那么我将不得不打破至少一个承诺。

The same can hold for the methods: if keeping one contract would mean breaking the other then it's in fact a bad idea to implement both interfaces . 对于这些方法也是如此:如果保留一个合同意味着打破另一个,那么implement这两个interfaces实际上是一个坏主意。

Edit :Contract broken, As per Class C signature It should implement two methods,but ultimately its implementing only one method and omitting another. 编辑 :合同损坏,按照Class C signature它应该实现两个方法,但最终它只实现一个method而省略另一个method

Reference 参考

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM