Java 中的抽象类(abstract class)和接口(interface)是两种常见的抽象化机制,它们都可以被用于定义一些具有一定抽象特性的东西,例如 API 或者系统中的某些模块。尽管抽象类和接口有着相似之处,但也有明显的区别。下面将详细介绍这两个概念的不同点。
1、抽象类
抽象类是指不能直接实例化的类,只能被用来派生其他类,它被设计成为仅包含可继承的方法、属性和变量。抽象类通常用于在类层次结构的根部建立一个适当的上下文语境。常见的抽象类特征如下:
- 抽象类可以包含成员变量和成员方法,也可以包含抽象方法以及非抽象方法。
- 抽象类必须通过关键字 abstract 进行声明,并且如果类中有一个或多个抽象方法,则该类必须被声明为抽象类。
- 抽象类可以被用来给其他类作为父类,抽象类的子类需要实现其中的所有抽象方法,否则子类也必须声明为抽象类。
以下是一个抽象类的示例代码:
代码语言:javascript复制public abstract class Shape {
protected double area;
public abstract double calculateArea();
public void printArea() {
System.out.println("The area of this shape is " area);
}
}
上面的代码中,Shape 是一个抽象类,它定义了一个受保护的成员变量 area 和一个抽象方法 calculateArea()。当继承 Shape 的具体子类实现 calculateArea() 方法之后,可以使用 printArea() 方法来打印出计算出来的面积。
2、接口
接口和抽象类一样也是一种特殊类型的类,它仅声明了一组或者多组方法以及常量,可以被看作是一个对外公开的 API 契约。接口在 Java 中属于比抽象类更加抽象的概念。常见的接口特征如下:
- 接口中只能包含常量、方法的声明(而非实现)以及内部定义的其他类型(如枚举类型或内部类)。
- 在接口中声明方法时必须使用关键字 public 或者 default 修饰,并且通常不需要使用 abstract 关键词,因为接口中所有方法都默认为抽象方法。
- 一个类可以实现多个接口,从而得到多个抽象函数的实现,表示它强制要求 Java 类实现该接口的相关方法。
- 除了 java.lang.Object 之外,任何类都可以实现一个接口,而无需拓展任何类。
- 接口中只有常量,没有变量。声明一个常量时必须使用 static 关键字,一般再加上 final 关键字使其成为常量。
下面是一个接口的示例代码:
代码语言:javascript复制java复制代码public interface Vehicle {
void run();
int getValue();
}
上面的代码定义了一个包含两个方法的接口 Vehicle,其中 run() 方法用于所有车辆的运行,而 getValue() 方法则用于获取车辆的价值。
3、抽象类和接口的区别
抽象类和接口都可以理解为一种模板或契约,它们之间虽然有相似点,但也存在很多不同之处。在下面的列表中,我们会总结这两种抽象机制的主要差异:
(1)、abstract class 可以包含普通成员变量,而 interface 只能包含静态常量(即 public static final)。
(2)、abstract class 可以包含非抽象方法,而 interface 中的所有方法都默认为抽象方法。
(3)、一个类只能继承一个 abstract class,但可以实现多个 interface。