为什么要有默认方法?
在 java 8 之前,接口与其实现类之间的耦合度太高了,当需要为一个接口添加方法时,所有的实现类都必须随之修改。默认方法它可以为接口添加新的方法,而不会破坏已有的接口的实现。
interface Fun{ default void foo(){ System.out.println("fun foo"); } } class A implements Fun { } public class Test { public static void main(String[] args) { A a = new A(); a.foo(); }
Java8中加入了默认方法的接口,这不就是以前的抽象类吗?其实,两者还是有区别的。
- 一个类只能继承一个抽象类;但是一个类可以实现多个接口。
- 抽象类有实例变量,而接口只能有类变量。
而接口的多继承会带来冲突:
- 类中的方法优先级最高,类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。
- 如果第一条无法判断,那么子接口的优先级更高:方法签名相同时,优先选择拥有最具体实现的默认方法的接口, 即如果B继承了A,那么B就比A更加具体。
- 最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法, 显式地选择使用哪一个默认方法的实现。
interface A { default void hello() { System.out.println(" A"); } } interface B extends A{ @Override default void hello() { System.out.println("B"); } } public class Test implements A,B{ public static void main(String[] args) { new Test().hello();//B } }
子接口优先级高
interface A { default void hello() { System.out.println(" A"); } } interface B extends A{ @Override default void hello() { System.out.println("B"); } } class D implements A { } public class Test extends D implements A ,B{ public static void main(String[] args) { new Test().hello();//B } }
虽然D继承了A,但是没有重写A中的方法,还是B
interface A { default void hello() { System.out.println(" A"); } } interface B extends A{ @Override default void hello() { System.out.println("B"); } } class D implements A { @Override public void hello() { System.out.println("D"); } } public class Test extends D implements A ,B{ public static void main(String[] args) { new Test().hello();//D }
子类优先级高