java8新特性之接口的默认方法

  |   0 评论   |   39 浏览

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");
    }
}

image.png
如果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 。因为实现类的路径要比接口更近,如图:
image.png

新增接口默认方法是为了更好的向下兼容。因为默认方法实现类不需要去实现该方法,所以对原来的一些实现类不会造成影响,如原来的系统中有个MyList类,实现了List接口,如果list新增了一个不是默认方法的方法,那么MyList编译就会出错,导致升级了版本应用编译通不过,这样对老版本的代码破坏是很大的,所以才引入了默认方法。

源码地址
代码在defaultmethod*包下。

也可以关注我的公众号:程序之声
图片
关注公众号,领取更多资源

本文为博主原创文章,未经博主允许不得转载。

评论

发表评论