Java 8允许我们使用default关键字向接口添加非抽象方法实现。来看下例子:
public interface UserService {
double calculate(int a);
default double sqrt(int a){
return Math.sqrt(a);
}
}
这里除了calculate方法外,还定义了sqrt默认方法,如果存在实现类,需要实现calculate方法,默认方法可以开箱即用,如:
public static void main(String[] args) {
UserService userService = new UserService(){
@Override
public double calculate(int a) {
return sqrt(a);
}
};
System.out.println(userService.calculate(100));//10
System.out.println(userService.sqrt(16));//4
}
上面的例子我们知道什么是接口的默认方法,下面再来看个例子
public interface MyInterface1 {
default void test(){
System.out.println("test1");
}
}
public interface MyInterface2 {
default void test(){
System.out.println("test2");
}
}
如果myClass都实现了MyInterface1和MyInterface2接口,那么MyClass不知道用哪个test,就会报错
public class MyClass implements MyInterface1,MyInterface2{
@Override
public void test() {
System.out.println("myClass");
}
}
那么需要现实test方法,这样就不会报错了,如果我们需要使用MyInterface1的test方法,应该怎么做?
public class MyClass implements MyInterface1,MyInterface2{
@Override
public void test() {
MyInterface1.super.test();
}
}
在来看下面的例子:
在新增一个MyInterfaceImpl
类,是MyInterface1
的实现类,如
public class MyInterfaceImpl implements MyInterface1{
@Override
public void test(){
System.out.println("test impl");
}
}
此时MyClass如下:
public class MyClass extends MyInterfaceImpl implements MyInterface2 {
public static void main(String[] args) {
MyClass myClass = new MyClass();
myClass.test();
}
}
这时候编译不会报错,编译器已经知道该使用哪个方法了,输出结果是test impl 。因为实现类的路径要比接口更近,如图:
新增接口默认方法是为了更好的向下兼容。因为默认方法实现类不需要去实现该方法,所以对原来的一些实现类不会造成影响,如原来的系统中有个MyList类,实现了List接口,如果list新增了一个不是默认方法的方法,那么MyList编译就会出错,导致升级了版本应用编译通不过,这样对老版本的代码破坏是很大的,所以才引入了默认方法。
源码地址
代码在defaultmethod*包下。
本文为博主原创文章,未经博主允许不得转载。
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载