Java8接口默认方法与静态方法
在Java8中,接口中可以声明默认方法和静态方法。
引入原因
默认方法主要优势是提供了一种扩展接口的方法,而不破坏现有代码。
向接口添加新方法是二进制兼容的,这意味着如果不重新编译该类,即使不实现新的方法,现有类的实现依旧可以运行。但是如果该类有重新编译的需求,则需要扩展新的方法,否则无法编译通过。
即:1.重新编译。2.使用到接口新增API。都会导致编译报错,都要求实现新增方法。
注意:函数式接口只包含一个抽象方法,默认方法是种非抽象方法。即函数式接口不会被默认方法影响。
引申,不同类型的兼容性
三种类型的兼容性,分别是:二进制级的兼容、源代码级的兼容,以及函数行为的兼容。
二进制级的兼容性表示现有的二进制执行文件能无缝持续链接(包括验证、准备和解析)和运行。比如,为接口添加一个方法就是二进制级的兼容,这种方式下,如果新添加的方法不被调用,接口已经实现的方法可以继续运行,不会出现错误。
源代码级的兼容性表示引入变化之后,现有的程序依然能成功编译通过。比如,向接口添加新的方法就不是源码级的兼容,因为遗留代码并没有实现新引入的方法,所以它们无法顺利通过编译。
函数行为的兼容性表示变更发生之后,程序接受同样的输入能得到同样的结果。比如,为接口添加新的方法就是函数行为兼容的,因为新添加的方法在程序中并未被调用(抑或该接口在实现中被覆盖了)
默认方法写法与通常用法
public interface MyInterface {
default String getMsg(String srcMsg){
return "MSG:"+srcMsg;
}
}
默认方法用法1:作为一种可选方法,有该需求的实现该方法。
interface Iterator<T> {
boolean hasNext();
T next();
default void remove() {
throw new UnsupportedOperationException();
}
}
默认方法用法2:提供默认的通用实现。如果某子类需要独特的处理方法时再特殊处理。
默认方法继承冲突的三条规则
(1) 类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。
(2) 如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更加具体。
(3) 最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现。
public class C implements B, A {
void hello(){
// 显示说明继承的是哪个接口
B.super.hello();
}
}
静态方法
接口定义的静态方法独立于任何对象调用。所以,在调用静态方法时,不需要实现接口,也不需要接口的实例,也就是说和调用类的静态方法的方式类似。语法如:接口名字.静态方法名。
注意,实现接口的类或者子接口不会继承接口中的静态方法。静态方法还是只与类有关。
public interface MyInterface {
static String getMsg(String msg){
return "静态方法:"+msg;
}
static void main(String[] args) {
System.out.println(MyInterface.getMsg("Static Method"));
}
}