【问题标题】:Implementing multiple interfaces having same method实现具有相同方法的多个接口
【发布时间】:2013-07-03 06:54:25
【问题描述】:

此代码完美运行。 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();

【问题讨论】:

标签: java oop interface overriding


【解决方案1】:

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

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 接口。

对于任何创建接口的人来说,使方法名称足够独特以减少名称冲突可能是一种好习惯。

【讨论】:

    【解决方案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();
       }
    }
    

    【讨论】:

    • 没有解释的代码不是答案
    【解决方案3】:

    因为它是一个接口,所以不会造成任何伤害。您基本上是通过实现ABC 类使用蓝图。 AB 都说 C 应该实现一个名为 test() 的方法

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

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

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

    【讨论】:

      【解决方案4】:

      JLS §8.4.8.4 说,

      使用重写等效签名继承方法

      一个类可以继承多个具有重写等效签名的方法(第 8.4.2 节)

      可能有几个路径可以从接口继承相同的方法声明。这个事实不会造成任何困难,而且它本身也不会导致编译时错误。

      理由似乎是,如果一个类有多个具有相同名称和签名的声明,因为该类可能通过多个路径继承了它们——例如实现一个接口并子类化一个实现该接口的类——没有伤害已经造成。

      【讨论】:

      • 如果两个接口中方法的返回类型不同怎么办?
      • @premktiw 编译错误。 JLS 中的关键短语是替代等效签名。在覆盖中更改返回类型是不合法的。
      【解决方案5】:

      就语法而言,但如果不遵守methods 之一的intent,则其合同已损坏,代码可被视为已损坏。。 p>

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

      方法也一样:如果保留一份合同就意味着破坏另一份合同,那么实际上implementinterfaces 都是一个坏主意。

      编辑:合同损坏,根据Class C signature 它应该实现两种方法,但最终它只实现一种method 而省略了另一种。

      Reference

      【讨论】:

      • 你能解释一下合同在哪里以及如何被破坏吗?
      • 合同损坏,根据 C 类签名它应该实现两种方法,但最终它只实现一种方法而省略了另一种方法。
      • 应该实现两个方法 ???它应该实现一个声明为 void test() 的方法,第二个在哪里?
      猜你喜欢
      • 2015-07-24
      • 2014-10-25
      • 1970-01-01
      • 2011-07-26
      • 2020-12-09
      • 2015-10-19
      • 1970-01-01
      • 2015-03-11
      • 2019-06-08
      相关资源
      最近更新 更多