默认方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public interface List <E> extends Collection <E> { ... default void replaceAll (UnaryOperator<E> operator) { Objects.requireNonNull(operator); final ListIterator<E> li = this .listIterator(); while (li.hasNext()) { li.set(operator.apply(li.next())); } } ... default void sort (Comparator<? super E> c) { Object[] a = this .toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i = this .listIterator(); for (Object e : a) { i.next(); i.set((E) e); } } ... ... }
接口类中支持申明带有实现的方法,可以由接口实现类的实例调用
和抽象类的区别 一个类只能继承一个抽象类;但是一个类可以实现多个接口。 抽象类有实例变量,而接口只能有类变量 多继承多实现中的优先级 由于一个类可以实现多个接口,所以当一个类继承了多个签名相同的方法,类在选择方法时的优先级规则:
类中的方法优先级最高,类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。 如果第一条无法判断,那么子接口的优先级更高:方法签名相同时,优先选择拥有最具体实现的默认方法的接口, 即如果B继承了A,那么B就比A更加具体。 最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法, 显式地选择使用哪一个默认方法的实现。 场景1: 1 2 3 4 5 public interface A { default void hello () { System.out.println("hello from A" ); } }
1 2 3 4 5 public interface B extends A { default void hello () { System.out.println("hello from B" ); } }
1 2 3 4 5 public class C implements A , B { public static void main (String[] args) { new C ().hello(); } }
类中无方法,B继承了A,故认为B中的hello()更具体,输出“hello from B”
场景2: 若C继承了A的实现类D
1 2 3 public class D implements A {}
1 2 3 4 5 6 public class C extends D implements A , B { public static void main (String[] args) { new C ().hello(); } }
C继承了D,但D没有对A的默认方法进行重写,故比较AB,还是输出“hello from B”
场景3: 若D中覆盖了A的默认方法
1 2 3 4 5 public class D implements A { public void hello () { System.out.println("hello from D" ); } }
父类中方法具有更高优先级,打印“hello from D”
场景4: 若B不再继承A
1 2 3 4 5 public interface A { default void hello () { System.out.println("hello from A" ); } }
1 2 3 4 5 public interface B { default void hello () { System.out.println("hello from B" ); } }
1 2 3 4 5 public class C implements A , B { public static void main (String[] args) { new C ().hello(); } }
由于编译器无法识别A还是B的实现更加具体,所以会抛出编译错误:“C inherits unrelated defaults for hello() from types A and B”。 解决冲突,可以在C中覆盖hello()方法并在方法内显示的选择调用A还是B的方法
1 2 3 4 5 6 7 8 9 10 11 public class C extends D implements A , B { public void hello () { B.super .hello(); } public static void main (String[] args) { new C ().hello(); } }