Java8 接口的默认方法
2020-03-25 本文已影响0人
巴巴11
Java 8中的接口现在
支持在声明方法的同时提供实现,这听起来让人惊讶!通过两种方式可以完成这种操作。其一,
Java 8允许在接口内声明静态方法。其二, Java 8引入了一个新功能,叫默认方法,通过默认方法
你可以指定接口方法的默认实现。换句话说,接口能提供方法的具体实现。因此,实现接口的类
如果不显式地提供该方法的具体实现,就会自动继承默认的实现。
默认方法由default修饰符修饰,并像类中声明的其他方法一样包含方法体。
默认方法是一种以源码兼容方式向接口内添加实现的方法。
使用默认方法的两种用例: 可选方法和行为的多继承:
1 可选方法
方便为了实现接口中不必要都实现的方法。
2 方法的多继承
继承不应该成为你一谈到代码复用就试图倚靠的万精油。
有些类被刻意地声明为final类型:声明为final的类不能被其他的类继承,
避免发生这样的反模式,防止核心代码的功能被污染。
通过精简的接口,可以最有效的获得方法的组合。
菱形继承问题:
public interface A {
default void hello() {
System.out.println("Hello from A");
}
}
public interface B extends A {
default void hello() {
System.out.println("Hello from B");
}
}
public class C implements B, A {
public static void main(String... args) {
new C().hello();
}
}
解决问题的三条规则:
如果一个类使用相同的函数签名从多个地方(比如另一个类或接口)继承了方法,通过三条
规则可以进行判断。
(1) 类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明为默认方法的优
先级。
(2) 如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先选择
拥有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更加具体。
(3) 最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现。
public interface A{
default void hello(){
System.out.println("Hello from A");
}
}
public interface B extends A { }
public interface C extends A { }
public class D implements B, C {
public static void main(String... args) {
new D().hello();
}
}
image.png
总结:
Java 8中的接口可以通过默认方法和静态方法提供方法的代码实现。
默认方法的开头以关键字default修饰,方法体与常规的类方法相同。
向发布的接口添加抽象方法不是源码兼容的。
默认方法的出现能帮助库的设计者以后向兼容的方式演进API。
默认方法可以用于创建可选方法和行为的多继承。
我们有办法解决由于一个类从多个接口中继承了拥有相同函数签名的方法而导致的冲突。
类或者父类中声明的方法的优先级高于任何默认方法。如果前一条无法解决冲突,那就
选择同函数签名的方法中实现得最具体的那个接口的方法。
两个默认方法都同样具体时,你需要在类中覆盖该方法,显式地选择使用哪个接口中提
供的默认方法