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

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

问题描述

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

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?

例如:

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

推荐答案

如果一个类型实现了两个接口,并且每个interface定义了一个具有相同签名的方法,那么实际上只有一个方法,它们是不可区分的.例如,如果这两个方法具有冲突的返回类型,那么它将是一个编译错误.这是继承、方法覆盖、隐藏和声明的一般规则,不仅适用于两个继承的interface 方法之间的可能冲突,也适用于interface 和一个super class 方法,甚至只是由于泛型的类型擦除而发生冲突.

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.

这里有一个例子,你有一个 interface Gift,它有一个 present() 方法(如,赠送礼物),还有一个 interface 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).

Presentable johnny 既是 Gift 也是 Guest.

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,无论是作为Gift还是作为Guest,都只有一种方法可以调用.

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 等效的示例:

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"
}

这进一步重申了从 interface 继承成员必须遵守成员声明的一般规则.这里我们有 GiftGuest 用不兼容的返回类型定义了 present():一个 void 另一个 布尔值.出于同样的原因,您不能在一种类型中使用 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 等效的方法,但要遵守方法覆盖和隐藏的通常要求.由于它们 ARE @Override 等效,因此实际上只有一种方法可以实现,因此没有什么可区分/选择的.

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天全站免登陆