java abstract class interface之间的区别介绍


在Java中,`abstract class`(抽象类)和`interface`(接口)都是用于定义一组方法或常量,但它们在用途和实现细节上存在显著的差异。下面是它们之间几个关键区别的介绍:

### 1. 方法的实现

- **抽象类**:可以包含抽象方法(没有方法体的方法)和具体实现的方法。抽象方法必须由子类实现,除非子类也是抽象的。

- **接口**:只能包含抽象方法(在Java 8之前)和常量(在Java 9之前,接口中的字段默认是`public static final`的)。从Java 8开始,接口中可以包含默认方法(有方法体)和静态方法。

### 2. 多继承

- **抽象类**:Java不支持类的多继承,即一个类只能继承自一个父类(可以是抽象类)。

- **接口**:Java支持接口的多实现,即一个类可以实现多个接口。

### 3. 字段

- **抽象类**:可以包含非静态的字段(实例变量),这些字段可以被子类继承。

- **接口**:在Java 8之前,接口中只能包含常量(`public static final`字段)。从Java 8开始,接口中可以包含非静态的字段,但这些字段必须是`final`的,并且隐式是`public static`的。

### 4. 访问修饰符

- **抽象类**:可以使用`public`、`protected`、`默认(无修饰符)`和`private`等访问修饰符来定义。但通常,抽象类被设计为`public`或`protected`,以便被其他类访问。

- **接口**:接口中的成员(方法和常量)默认是`public`的,不能定义为`private`或`protected`。

### 5. 构造函数

- **抽象类**:可以有构造函数,这些构造函数主要用于初始化抽象类中的字段,或者在子类构造对象时被调用。

- **接口**:不能有构造函数,因为接口不能被实例化。

### 6. 使用场景

- **抽象类**:用于表示一种“是”(is-a)关系,当你想定义一个通用的模板,并希望子类遵循这个模板,但又不想立即实现所有方法时,可以使用抽象类。

- **接口**:用于表示一种“有”(has-a)关系,即定义了一组方法规范,但不实现它们。它主要用于定义一组API,让不同的类去实现这些API,以实现特定的功能。

综上所述,`abstract class`和`interface`在Java中各有其用途和限制,选择使用哪一个取决于具体的设计需求和场景。