16

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

5 回答 5

16

因为它是一个接口,所以不会造成任何伤害。您基本上是C通过实现A和来为您的课程使用蓝图B。两者都说应该实现一个名为的A方法BCtest()

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

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

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

于 2013-07-05T08:30:04.333 回答
7

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

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具有相同方法签名的接口。

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

于 2016-11-03T02:21:38.650 回答
6

JLS §8.4.8.4说,

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

一个类可以继承多个具有重写等效签名的方法(第 8.4.2 节)
……<br> 可能有多个路径可以从接口继承相同的方法声明。这个事实不会造成任何困难,而且它本身也不会导致编译时错误。

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

于 2013-07-05T08:33:03.093 回答
2

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

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

方法也是如此:如果保留一份合同意味着破坏另一份合同,那么这对implement双方来说实际上都是一个坏主意interfaces

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

参考

于 2013-07-05T08:28:51.103 回答
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();
   }
}
于 2013-10-15T11:49:13.473 回答