Java 8中接口中使用默认方法的意外行为

Ray*_*yek 1 default interface java-8

以下类在运行时打印"M".我有点期待"G".

谁能解释这种行为?

interface G {
    default void print() {
        System.out.println("G");
    }
}
class M {
    public void print() {
        System.out.println("M");
    }
}
class GImpl extends M implements G {}
public class Wierd {
    public static void main(String[] args) {
        G g=new GImpl();
        g.print();
    }
}
Run Code Online (Sandbox Code Playgroud)

ski*_*iwi 5

默认方法用作一种备份方法,这意味着只有在没有该方法的具体实现时才会调用它们.

在查看您的课程时,我们有这样的遭遇顺序:

  1. GImpl,哪个电话print().
  2. GImpl没有print(),所以上了树.
  3. M确实有print(),所以使用那个.

我看到你使用的唯一地方G是变量类型,完全没问题,就像GImpl a-a一样 G.

如果您想调用G方法,请考虑以下事项:

interface G {
    default void print() {
        System.out.println("G");
    }
}
class M {
}
class GImpl extends M implements G {}
public class Weird {
    public static void main(String[] args) {
        G g=new GImpl();
        g.print();
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们有以下顺序:

  1. GImpl,哪个电话print().
  2. GImpl没有print(),所以上去.
  3. M没有print(),上升.
  4. 只有G左边,它有一个默认的实现print(),所以被调用.注意:如果没有,您的代码甚至不会编译.

因此,使用默认方法,您无法覆盖已存在的行为.但是,当没有其他行为时,您可以添加行为.