美文网首页
JDK8接口新特性:默认方法

JDK8接口新特性:默认方法

作者: 某程序猿 | 来源:发表于2018-09-01 22:10 被阅读0次

    默认方法

    在jdk8中关于接口新增一个特性,就是interface可以有默认方法。
    例如定义一个Named接口:

    public interface Named {
        default String getName() {
            return "nathan, by default";
        }
    }
    

    假如你是1.8以下版本,这样写肯定连编译都通不过。可能有都同学会问,接口又不能实例化,增加这个方法都意义何在?在以往的java API中包含了很多伴随方法,如Collection/AbstractCollection,AbstractCollection实现了Collection中的部分方法。在jdk8中,就不需要这么做,直接使用default 关键字就能实现默认方法了,这样会使得代码结构更加精简。
    现在我们来实现这个接口,定义一个NameNobody,但是不实现该方法:

    public class NamedNobody implements Named {
    }
    

    接下来编写一个测试类:

    public class Main {
    
        public static void main(String[] args) {
            Named named = new NamedNobody();
            System.out.println(named.getName()); // nathan, by default
        }
    }
    

    执行结果:

    nathan, by default
    

    可以看到即使没有实现接口方法,也会自动调用接口内的默认实现。

    方法冲突

    大家都知道,java是允许一个类同时实现多个接口的,现在有一个Person接口,也有一个getName方法

    public interface Person {
    
        default String getName() {
            return "Person, by default";
        }
    }
    

    然后有一个Student类同时实现了Person和Named接口

    public class Student implements Named, Person {
    
        @Override
        public String getName() {
            return "student";
        }
    }
    

    此时Student必须实现getName方法,否则编译不通过。

    public class Main {
    
        public static void main(String[] args) {
            Named student = new Student();
            System.out.println(student.getName());
        }
    }
    

    执行结果:

    student
    

    我们接下来看更一个更复杂的情况,有NamedPerson类,拥有一个getName方法

    public class NamedPerson {
    
        public String getName() {
            return "NamedPerson";
        }
    }
    

    还有个Staff类,继承了NamedPerson,实现了Named接口

    public class Staff extends NamedPerson implements Named {
    
    }
    

    此时不实现Named中的抽象方法也不会报错,我们来运行以下看看:

    public class Main {
    
        public static void main(String[] args) {
            Staff staff = new Staff();
            System.out.println(staff.getName());
        }
    }
    

    执行结果:

    NamedPerson
    

    可以看到实际调用的是父类中的方法。


    结构图.png

    上图是整个demo的继承关系。
    通过上面两个例子,我们可以总结出两条解决冲突的规则:

    • 接口冲突:如果一个类同时实现了具有相同方法签名的接口,则该类必须覆盖该抽象方法。
    • 超类冲突:超类和接口提供相同方法签名的方法,此时子类要是不覆盖,则默认调用超类方法。

    相关文章

      网友评论

          本文标题:JDK8接口新特性:默认方法

          本文链接:https://www.haomeiwen.com/subject/haouwftx.html