在抽象类中,抽象方法本质上是定义接口规范:即规定高层类的接口,从而保证所有子类都有相同的接口实现,这样,多态就能发挥出威力。
如果一个抽象类没有字段,所有方法全部都是抽象方法:

abstract class Person {
    public abstract void run();
    public abstract String getName();
}

就可以把该抽象类改写为接口:interface

在Java中,使用interface可以声明一个接口:

interface Person {
    void run();
    String getName();
}

所谓interface,就是比抽象类还要抽象的纯抽象接口,因为它连字段都不能有。因为接口定义的所有方法默认都是public abstract的,所以这两个修饰符不需要写出来(写不写效果都一样)。

当一个具体的class去实现一个interface时,需要使用implements关键字。例子:

class Student implements Person {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(this.name + " run");
    }

    @Override
    public String getName() {
        return this.name;
    }
}

在Java中,一个类只能继承自另一个类,不能从多个类继承。但是,一个类可以实现多个interface,例如:

class Student implements Person, Hello { // 实现了两个interface
    ...
}

术语

注意区分术语:

Java的接口特指interface的定义,表示一个接口类型和一组方法签名,而编程接口泛指接口规范,如方法签名,数据格式,网络协议等。

抽象类和接口的对比如下:

abstract classinterface
继承只能extends一个class可以implements多个interface
字段可以定义实例字段不能定义实例字段
抽象方法可以定义抽象方法可以定义抽象方法
抽象方法可以定义非抽象方法可以定义default方法

接口继承

一个interface可以继承自另一个interfaceinterface继承自interface使用extends,它相当于扩展了接口的方法。例如:

interface Hello {
    void hello();
}

interface Person extends Hello {
    void run();
    String getName();
}

此时,Person接口继承自Hello接口,因此,Person接口现在实际上有3个抽象方法签名,其中一个来自继承的Hello接口。
继承关系
在使用的时候,实例化的对象永远只能是某个具体的子类,但总是通过接口去引用它,因为接口比抽象类更抽象:

List list = new ArrayList(); // 用List接口引用具体子类的实例
Collection coll = list; // 向上转型为Collection接口
Iterable it = coll; // 向上转型为Iterable接口

default方法

在接口中,可以定义default方法。例如,把Person接口的run()方法改为default方法:

public class Main {
    public static void main(String[] args) {
        Person p = new Student("Xiao Ming");
        p.run();       //Xiao Ming run 
    }
}

interface Person {
    String getName();
    default void run() {
        System.out.println(getName() + " run");
    }
}

class Student implements Person {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

实现类可以不必覆写default方法。default方法的目的是,当需要给接口新增一个方法时,会涉及到修改全部子类。如果新增的是default方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法。

default方法和抽象类的普通方法是有所不同的。因为interface没有字段,default方法无法访问字段,而抽象类的普通方法可以访问实例字段。

THE END
最后修改:2020 年 03 月 31 日 16 : 27
本文链接:https://www.j000e.com/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/interface.html
版权声明:本文『[接口][interface][implements][术语][接口继承][继承关系][default方法]』为『Joe』原创。著作权归作者所有。
转载说明:[接口][interface][implements][术语][接口继承][继承关系][default方法] || Joe's Blog』转载许可类型见文末右下角标识。允许规范转载时,转载文章需注明原文出处及地址。
Last modification:March 31, 2020