浅谈JDK 1.8后接口方法默认采用的关键字——default

前言

在实现拦截器功能的时候偶然观摩源码的时候发现,继承HandlerInterceptor接口中使用了default关键字

在jdk1.8之前,该关键字只用在switch语句中当作case之外的其他情况来使用

而在之后,该default默认用来修饰接口中的具体方法,并无需被实现该接口的类重写

这样确实解决了每次继承后重写具体方法的繁杂过程,但是也出现了很多新的问题

即实现两个接口中存在相同的方法的情况、继承父类中和实现接口中存在相同方法的情况,我们通过例子来求证一下

正文

首先我们来模拟一个类实现两个拥有相同方法的接口
// 接口1
public interface DefalutInterface {
    default void soutDefalut() {
        System.out.println("这是接口实现的方法");
    }
}

// 接口2
public interface DefalutInterface01 {
    default void soutDefalut() {
        System.out.println("这是接口01实现的方法");
    }
}

// 具体实现类
public class DefalutTest implements DefalutInterface, DefalutInterface01 {
    public DefalutTest() {
    }

    public void soutDefalut() {
        System.out.println("自己实现的方法");
    }
}

// 测试方法
public class Test {
    public static void main(String[] args) {
        DefalutTest defalutTest = new DefalutTest();
        defalutTest.soutDefalut();
    }
}
结论是如果实现类自己重新实现了重复的方法,则默认使用新实现的方法

如果不重新实现,则编译时就会报错,警告两个接口中存在不相关的默认值

接着测试如果测试类同时继承的父类和实现的接口中同时存在相同的方法
// 接口
public interface DefalutInterface {
    default void soutDefalut() {
        System.out.println("这是接口实现的方法");
    }
}

// 父类
public class DefaultSuperClass {
    public void soutDefalut() {
        System.out.println("这是父类实现的方法");
    }
}

// 测试类
public class DefalutTest extends DefaultSuperClass implements DefalutInterface{
    public DefalutTest() {
    }

    @Override
    public void soutDefalut() {
        super.soutDefalut();
    }

//    @Override
//    public void soutDefalut() {
//        DefalutInterface.super.soutDefalut();
//    }
}

 // 测试方法
public class Test {
    public static void main(String[] args) {
        DefalutTest defalutTest = new DefalutTest();
        defalutTest.soutDefalut();
    }
}
结果告诉我们如果我们不声明重复的方法,就会像测试类中的那样默认重写父类的方法来实现

但是如果你像注释的代码一样声明用哪一个方法,也可以采用接口中的具体方法

总结

经过两个例子的展示,default在遇到两个接口中存在相同方法的情况会报错

在父类和接口存在相同方法的情况会默认采用父类中的方法,也可以自行选择

如果文章存在问题和更深的理解,欢迎在评论区扶正和评论,各自努力,最高处见
posted @ 2021-11-24 11:56  21岁还不是架构师  阅读(282)  评论(0编辑  收藏  举报