Cod*_*roc 6 java java-8 default-method
考虑以下情况,
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");
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我得到了非常期待的输出.
Test
Test
Test
Run Code Online (Sandbox Code Playgroud)
我一直在阅读有关Java-8
默认方法的内容,特别是有关扩展包含默认方法的接口的内容
2 nd bullet:重新声明默认方法,使其成为抽象方法.
在上面的例子中,我有这有相同名称的默认方法两个接口,当我实现了这两个我才能够达到执行printHello
的Test
是指IFace2
.
我对此几乎没有疑问,
printHello
方法IFace1
和如果我不能比,为什么?IFace1
这可通过其他方法现在阴影?引用说,你可以在它的子界面中制作default
方法abstract
.例如,
interface IFace2 extends IFace1 {
void printHello();
}
Run Code Online (Sandbox Code Playgroud)
在这里,当我实现时,我IFace2
实际上无法达到default
方法,IFace1
这正是我案例中发生的事情.
看来你对default
方法的存在感到有点困惑.所以,让我们忘记IFace1.printHello()
一个default
方法.那么,有一个明显的情况:Test
实现两个接口,IFace1
并且IFace2
碰巧有一个具有相同名称和签名的方法.
Test
实现该方法,从而实现两个接口的方法.default
方法的新特性不会改变这种逻辑.此外,语言设计者注意添加default
方法不会影响现有代码的行为,因此如果您的类实现了该方法,则方法的存在default
变得无关紧要.
但是,如果您编写的代码知道方法的存在default
,则可以调用它,如果它是由直接超级接口声明或继承的,即在您的代码中可以IFace1.super.printHello()
用来调用default
方法IFace1
.
这些规则与超类规则没有太大区别.如果更改接口以使接口IFace2
扩展IFace1
并仍然声明printHello()
为abstract
方法,则此abstract
方法会覆盖该default
方法,您无法再IFace1.super.printHello()
从内部调用Test
.
如上所述,这些规则与普通实例方法没有太大区别.如果Test
声明了一个方法printHello()
,那么这是您可以通过对实例的引用调用的唯一方法Test
,无论其声明的类型是Test
,IFace1
还是IFace2
.只有Test
自身的实现方法可以进行super
调用.
当涉及可能的接口多重继承时,主要区别就在起作用.如果你的类Test
没有不实施该方法printHello()
,它取决于两个接口的继承关系,会发生什么
IFace2
extends IFace1
,那么它的抽象方法会重新声明该default
方法,因此会发生编译器错误,因为Test
必须实现该abstract
方法IFace2
没有扩展IFace1
,则存在两个具有相同名称和签名的可继承方法,因此Test
不会继承该default
方法,并且会发生编译器错误,因为Test
必须实现该abstract
方法IFace1
extends IFace2
,Test
将继承该default
方法.如果Test
没有实现它也将继承它IFace2
,但这应该是一个惊喜......我怎样才能到达 IFace1 的 printHello 方法,如果我不能,为什么?
你只能一个类型的实例方法内这样做实现IFace1
有
IFace1.super.printHello(); // only if IFace1 declares a default implementation of the method
Run Code Online (Sandbox Code Playgroud)
换句话说,您不能通过简单的类型IFace1
或Test
(或其他)引用来做到这一点。那会破坏封装。
这种行为不会让我远离 IFace1 的预期性质,现在可能被其他方法遮蔽了吗?
这里没有阴影。您已经覆盖了该方法,因此调用了覆盖的方法。
关于你的第三个问题,你没有扩展任何接口,所以我没有看到相关性。
如果你真的有
interface IFace2 extends IFace1 {
void printHello();
}
Run Code Online (Sandbox Code Playgroud)
和
public class Test implements IFace2 {
Run Code Online (Sandbox Code Playgroud)
那么您将无法访问该方法IFace1
的default
实现。你永远不能跳过超类型来访问继承层次结构中更高的实现。
归档时间: |
|
查看次数: |
501 次 |
最近记录: |