阴影接口的默认方法 [英] Shadowing default method of an interface

查看:144
本文介绍了阴影接口的默认方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下情况,

interface IFace1 {
    default void printHello() {
        System.out.println("IFace1");
    }
}

interface IFace2 {
    void printHello();
} 

public class Test implements IFace1, IFace2 {

    public static void main(String[] args) {
        Test test = new Test();
        test.printHello();

        IFace1 iface1 = new Test();
        iface1.printHello();

        IFace2 iface2 = new Test();
        iface2.printHello();
    }

    @Override
    public void printHello() {
        System.out.println("Test");
    }
}

在上面的示例中,我得到以下输出,即相当预期。

In above example I am getting following output which is quite expected.

Test
Test
Test

我一直在阅读 Java-8 默认方法和特别是关于扩展包含默认方法的界面

I have been reading about Java-8 default methods and specifically about Extending Interfaces That Contain Default Methods


2 nd bullet:重新声明默认方法,使其成为抽象方法。

2nd bullet : Redeclare the default method, which makes it abstract.

在上面的示例中,我有两个接口,它们具有相同名称的默认方法,当我实现这两个接口时,我只能实现 printHello 测试,它指的是 IFace2

In above example where I have two interfaces which have default method with same name and when I implemented both I was only able to reach to the implementation of printHello of Test which refers to IFace2.

我对此几乎没有任何疑问,

I have few questions about this,


  1. 我如何到达 printHello m IFace1 的方法,如果我不能为什么?

  2. 这种行为是不是让我远离 IFace1 的预期性质,现在可能被其他方法遮蔽?

  1. How can I reach to the printHello method of IFace1 and if I can't than why ?
  2. Doesn't this behavior keep me away from the intended nature of IFace1 which is may be now shadowed by other method ?






引用说,你可以赚默认方法 abstract 在它的子界面中。 例如,


Quote says, you can make the default method abstract in it's child interface. For example,

interface IFace2 extends IFace1 {
    void printHello();
}

这时我实施 IFace2 我实际上无法达到默认 IFace1 的方法,这正是我案例中发生的事情。

Here when I implement IFace2 I won't be actually able to reach default method of IFace1 that is exactly what is happening in my case.

推荐答案

您似乎对默认方法。所以,让我们暂时忘记 IFace1.printHello()默认方法。那么,有一个明显的情况:测试实现两个接口, IFace1 IFace2 ,碰巧有一个具有相同名称和签名的方法。

It seems that you are a bit confused by the presence of a default method. So let’s forget for a moment that IFace1.printHello() is a default method. So then, there is a clear situation: Test implements two interfaces, IFace1 and IFace2, which happen to have a method with the same name and signature.

测试 implements该方法因此实现了两个接口的方法。 默认方法的新功能不会改变有关此逻辑的任何内容。此外,语言设计人员注意添加默认方法不会影响现有代码的行为,因此如果您的类实现该方法,则存在 default 方法变得无关紧要。

Test implements that method and therefore implements the method for both interfaces. The new feature of default methods does not change anything about this logic. Moreover, the language designers took care that adding a default method does not affect the behavior of existing code, so if your class implements the method, the presence of default methods becomes irrelevant.

但是,如果您编写的代码知道 default 方法,您可以调用它,如果它是由直接超级接口声明或继承的,即在您的代码中您可以使用 IFace1.super.printHello()调用 IFace1 默认方法。

However, if you write code that is aware of the presence of default methods, you may invoke it, if it is declared or inherited by a direct super interface, i.e. in your code you may use IFace1.super.printHello() to invoke the default method of IFace1.

规则与超类规则没有太大差别。如果您更改接口以使接口 IFace2 扩展 IFace1 并仍然声明 printHello()作为 abstract 方法,然后这个 abstract 方法会覆盖默认方法,你不能从测试 IFace1.super.printHello() >再过。

The rules are not much different to the rules of super classes. If you change the interfaces so that interface IFace2 extends IFace1 and still declares printHello() as an abstract method, then this abstract method does override the default method and you can’t invoke IFace1.super.printHello() from within Test anymore.

如上所述,这些规则与普通实例方法没有太大区别。如果 Test 声明一个方法 printHello(),那就是你可以调用的 only 方法通过引用 Test 实例,无论其声明的类型是否为 Test IFace1 IFace2 。只有 Test 的实现方法本身可以执行 super 调用。

As said, these rules are not much different to ordinary instance methods. If Test declares a method printHello(), that’s the only method that you can invoke by a reference to a Test instance, regardless whether its declared type is Test, IFace1 or IFace2. Only implementation methods of Test itself may do super invocations.

当涉及可能的接口多重继承时,主要区别就在起作用。如果您的类测试 实现方法 printHello(),则取决于两个接口的继承关系,会发生什么

The main difference comes into play when the possible multiple inheritance of interfaces is involved. If your class Test does not implement the method printHello(), it depends on the inheritance relationship of the two interfaces, what will happen


  • 如果 IFace2 extends IFace1 ,它的抽象方法重新声明默认方法,因此发生编译错误,如 Test 必须实现 abstract 方法

  • 如果 IFace2 确实如此不扩展 IFace1 ,有两个具有相同名称和签名的可继承方法,因此 Test 将不会继承默认方法,并且发生编译器错误,因为 Test 必须实现 abstract 方法

  • 如果 IFace1 extends IFace2 Test 将继承默认方法。如果测试没有实现 IFace2 ,它也将继承它,但这应该是一个惊喜......

  • If IFace2 extends IFace1, it’s abstract method redeclares the default method, hence a compiler error occurs, as Test must implement the abstract method
  • If IFace2 does not extend IFace1, there are ambiguously two inheritable methods with the same name and signature, therefore Test will not inherit the default method, and a compiler error occurs, as Test must implement the abstract method
  • If IFace1 extends IFace2, Test will inherit the default method. It will also inherit it if Test does not implement IFace2, but this should come at a surprise…

这篇关于阴影接口的默认方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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