使用相同的方法在类中实现两个接口。覆盖哪种接口方法? [英] Implementing two interfaces in a class with same method. Which interface method is overridden?

查看:383
本文介绍了使用相同的方法在类中实现两个接口。覆盖哪种接口方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两个具有相同方法名称和签名的接口。但是由单个类实现,那么编译器将如何识别哪个方法适用于哪个接口?

Two interfaces with same method names and signatures. But implemented by a single class then how the compiler will identify the which method is for which interface?

Ex:

interface A{
  int f();
}

interface B{
  int f();
}

class Test implements A, B{   
  public static void main(String... args) throws Exception{   

  }

  @Override
  public int f() {  // from which interface A or B
    return 0;
  }
}   


推荐答案

如果一个类型实现两个接口,每个接口定义一个具有相同签名的方法,然后实际上只有一个方法,并且它们是不可区分的。例如,如果这两种方法具有冲突的返回类型,那么它将是编译错误。这是继承,方法重写,隐藏和声明的一般规则,并且还适用于不仅在2个继承的接口方法之间的可能冲突,而且还适用于 interface 和一个超级方法,甚至只是由于类型擦除泛型而产生的冲突。

If a type implements two interfaces, and each interface define a method that has identical signature, then in effect there is only one method, and they are not distinguishable. If, say, the two methods have conflicting return types, then it will be a compilation error. This is the general rule of inheritance, method overriding, hiding, and declarations, and applies also to possible conflicts not only between 2 inherited interface methods, but also an interface and a super class method, or even just conflicts due to type erasure of generics.

这是一个示例,其中有一个界面礼物,它有一个 present()方法(如赠送礼物),还有一个界面Guest ,它还有一个 present()方法(如同客人在场但不在场)。

Here's an example where you have an interface Gift, which has a present() method (as in, presenting gifts), and also an interface Guest, which also has a present() method (as in, the guest is present and not absent).

可呈现的约翰尼既是礼物又是来宾

public class InterfaceTest {
    interface Gift  { void present(); }
    interface Guest { void present(); }

    interface Presentable extends Gift, Guest { }

    public static void main(String[] args) {
        Presentable johnny = new Presentable() {
            @Override public void present() {
                System.out.println("Heeeereee's Johnny!!!");
            }
        };
        johnny.present();                     // "Heeeereee's Johnny!!!"

        ((Gift) johnny).present();            // "Heeeereee's Johnny!!!"
        ((Guest) johnny).present();           // "Heeeereee's Johnny!!!"

        Gift johnnyAsGift = (Gift) johnny;
        johnnyAsGift.present();               // "Heeeereee's Johnny!!!"

        Guest johnnyAsGuest = (Guest) johnny;
        johnnyAsGuest.present();              // "Heeeereee's Johnny!!!"
    }
}

以上代码段编译并运行。

The above snippet compiles and runs.

请注意只有一个 @Override 必要!!! 。这是因为 Gift.present() Guest.present() @Override -equivalent( JLS 8.4.2 )。

Note that there is only one @Override necessary!!!. This is because Gift.present() and Guest.present() are "@Override-equivalent" (JLS 8.4.2).

因此, johnny 只有一个实现 present(),无论你如何对待 johnny ,无论是否为礼物或作为访客,只有一种方法可以调用。

Thus, johnny only has one implementation of present(), and it doesn't matter how you treat johnny, whether as a Gift or as a Guest, there is only one method to invoke.

以下是两个继承方法不是 @Override的示例 -equivalent:

Here's an example where the two inherited methods are NOT @Override-equivalent:

public class InterfaceTest {
    interface Gift  { void present(); }
    interface Guest { boolean present(); }

    interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
    // "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
    //  both define present(), but with unrelated return types"
}

这进一步重申从接口继承成员必须遵守成员声明的一般规则。这里我们有礼物访客定义 present()不兼容的返回类型:一个 void 另一个 boolean 。出于同样的原因,你不能在一种类型中使用 void present() boolean present(),此示例导致编译错误。

This further reiterates that inheriting members from an interface must obey the general rule of member declarations. Here we have Gift and Guest define present() with incompatible return types: one void the other boolean. For the same reason that you can't an void present() and a boolean present() in one type, this example results in a compilation error.

您可以继承 @Override -equivalent的方法,这取决于方法覆盖和隐藏的常规要求。由于它们 ARE @Override -equivalent,实际上只有一种方法可以实现,因此无需区分/选择。

You can inherit methods that are @Override-equivalent, subject to the usual requirements of method overriding and hiding. Since they ARE @Override-equivalent, effectively there is only one method to implement, and thus there's nothing to distinguish/select from.

编译器不必识别哪个接口的方法,因为一旦确定它们是 @Override - 等价,它们是相同的方法。

The compiler does not have to identify which method is for which interface, because once they are determined to be @Override-equivalent, they're the same method.

解决潜在的不兼容问题可能是一项棘手的任务,但这完全是另一个问题。

Resolving potential incompatibilities may be a tricky task, but that's another issue altogether.

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆