原文链接:https://www.cnblogs.com/Time25/p/19867384.html

什么是接口

如果一个抽象类没有任何字段的话,那可以把他抽象成一个接口,接口更加抽象

1
2
3
4
abstract class Person {
public abstract void run();
public abstract String getName();
}

转变成
1
2
3
4
interface Person {
void run();
String getName();
}

当一个具体的class要去实现接口的时候,要用implements这个关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
}
}

一个类只可以继承一个类,但是可以实现多个接口

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

一些术语

image

接口可以继承,相当于扩展了接口的功能

1
2
3
4
5
6
7
8
interface Hello {
void hello();
}

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

合理的继承关系

image

这里用java中的List举例,箭头是子类指向父类
抽象类AbstractList实现接口List,然后ArrayList和LinkedList继承AbstractList
在使用的时候,实例化的对象永远只能是某个具体的子类,但总是通过接口去引用它,因为接口比抽象类更抽象:

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

default方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// interface
public class Main {
public static void main(String[] args) {
Person p = new Student("Xiao Ming");
p.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方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法。
更详细的解释是:现在所有实现了你这个接口的类都有这个run这个方法了,你要是不覆写的话,那就是这个run方法了,当然你可以在某个类中覆写这个run,这样这个类里就有新的run函数了
default方法和抽象类的普通方法是有所不同的。因为interface没有字段,default方法无法访问字段,而抽象类的普通方法可以访问实例字段。

// TRAINING LOG · 第 51 / 76 篇训练记录 · 成文于 2026.04.14 · 夜间 19:32