Java8新特性之default关键字学习

先谈一谈抽象类和接口的区别

抽象类

可看做是不可实例化的普通类,可以拥有构造方法,可以有main方法

抽象类中的方法可以是抽象方法(抽象方法必须存在于抽象类中),也可以是普通方法、静态方法

可以声明变量,不是必须赋初值。

抽象类可以继承其它类,也可实现接口

抽象类的派生类,必须覆盖父类中abstract修饰的所有方法

接口

接口仅可继承其他接口,不可继承其它类或实现另外的接口

接口中的方法默认为abstract类型

接口中声明的变量必须赋初值,且不可再改变,因为所有变量都是static final类型的

对于JDK7及以前版本:

1. 接口中的方法不可有方法体(因为默认是抽象方法),不可有静态方法。

2. 接口的实现类,必须实现接口中的所有方法(包括接口本身的和从其它接口继承的)

对于JDK8及以后版本:

1. 接口中default方法可有方法体,也可在接口里写静态方法。

2. 接口的实现类,必须实现接口中除default类型的其它所有方法(包括接口本身的和从其它接口继承的)

再说说default关键字:

自Java8加入

用来修饰方法,使得在接口中的方法可以写入方法体

接口的实现类若没有实现(也可以叫覆盖)default类型的方法,则可在实现类中直接调用(接口says:你不覆盖,那就按这个默认的来了啊)。否则,是正常的覆盖,实现多态。

个人理解:

1. default的加入,使得我们在接口类中增加方法时,不必一个个地改动实现类了(添加一个default方法时,实现类可以不去管),使得接口和抽象类更为贴近了一步。

2. 很多的抽象类可以被精简掉了,实现接口的抽象类中写的方法体代码可以直接移到接口中,派生类直接实现接口即可,具体可以看WebMvcConfigurerAdapter被废弃的例子

附上一个实验例子,两个接口是继承关系,一个类来实现其中一个接口,实验各种调用:

interface BaseRadio {

    void sent(String a,String b);

    int port = 9800;

    default void close() {
        System.out.println(port);
        System.out.println("关了");
    }

    static void prt(){
        System.out.println("uvb77");
    }

    default void open() {
        System.out.println("打开");
    }
}
interface Radio extends BaseRadio {

    void sent();

    void sent(int s);

    int sent(String a);

    @Override
    default void close() {
        System.out.println(port + 1);
        System.out.println("我是Radio重写的");
    }

    static void prt(){
        System.out.println("uvb76");
    }

}
public class TestRadio implements Radio {

    @Override
    public void sent() {
        System.out.println("我是BaseRadio里的");
    }

    @Override
    public void sent(int s) {
        System.out.println("我是BaseRadio里的");
    }

    @Override
    public int sent(String a) {
        System.out.println("我是BaseRadio里的");
        return 0;
    }

    @Override
    public void sent(String a, String b) {
        System.out.println("我是Radio里的!!!!!");
    }

    @Override
    public void close() {
        System.out.println(port + 2);
        System.out.println("我是TestRadio重写的");
    }

    public static void main(String[] args) {
        TestRadio testRadio = new TestRadio();
        System.out.println("调用实现类覆盖的default方法,经过了2次覆盖,已经和原来完全不同了:");
        testRadio.close();
        System.out.println("实现类调用BaseRadio接口的default方法,就好像自己的方法哦:");
        testRadio.open();

        System.out.println("打印接口里声明的port:" + TestRadio.port);
        Radio.prt();
        System.out.println("调用接口的静态方法");
        BaseRadio.prt();
    }
}

最终输出如下:

调用实现类覆盖的default方法,经过了2次覆盖,已经和原来完全不同了:
9802
我是TestRadio重写的


实现类调用BaseRadio接口的default方法,就好像自己的方法哦:
打开


打印接口里声明的port:9800
uvb76


调用接口的静态方法
uvb77

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章