接口和抽象类:
- 具体类——抽象类——接口:越来越抽象,内部实现的东西越来越少
抽象类
- 抽象类为复用而生:专门作为基类来使用,也具有解耦的功能。
- 抽象类是未完全实现逻辑的类(可以有字段和和具体方法,他们代表了 “具体逻辑”)
- 抽象类封装**的是确定的,开放的是不确定的**,推迟到合适的子类中去实现。
抽象类和抽象⽅法都使⽤ abstract 关键字进⾏声明。如果⼀个类中包含抽象⽅法,那么这个类必须声明为抽象类。
抽象类和普通类最⼤的区别是,抽象类不能被实例化,只能被继承。
接⼝
-
接口是完全未实现逻辑的 “类”,在 Java 8 之前,它不能有任何的⽅法实现。
-
从 Java 8 开始,接⼝也可以拥有默认的⽅法实现,这是因为不⽀持默认⽅法的接⼝的维护成本太⾼了。在 Java 8 之前,如果⼀个接⼝想要添加新的⽅法,那么要修改所有实现了该接⼝的类,让它们都实现新增的⽅法。
-
在 Java 9之前,接⼝的成员(字段 + ⽅法)默认都是 public 的,并且不允许定义为 private 或者 protected。从 Java 9开始,允许将⽅法定义为 private,这样就能定义某些复⽤的代码⼜不会把⽅法暴露出去。
-
接⼝的字段默认都是 static final 的,即静态常量
public interface InterfaceExample {
void func1();
default void func2(){
System.out.println("func2");
}
int x = 123;
// int y; //报错,变量没有初始化
public int z = 0; // 警告,'public' 是多余的
// private int k = 0; // 报错 'private' 不允许
// protected int l = 0; // 报错 'protected' 不允许
// private void fun3(); // 报错 'private' 不允许
}
比较
-
接口和抽象类都不能实例化
-
类可以实现多个接口,弥补了Java单继承的局限性。
-
接⼝的字段只能是 static final 类型的,⽽抽象类的字段没有这种限制。
使⽤选择
使⽤接⼝:
-
需要让不相关的类都实现⼀个⽅法。
-
需要使⽤多重继承。
使⽤抽象类:
-
需要在⼏个相关的类中共享代码。
-
需要继承⾮静态和⾮常量字段。
在很多情况下,接⼝优先于抽象类。因为接⼝没有抽象类严格的类层次结构要求,可以灵活地为⼀个类添加⾏为。