Java 抽象类 vs 接口(Abstract Class vs Interface)对比笔记
一、基本定义
概念 | 抽象类 (abstract class ) | 接口 (interface ) |
---|---|---|
定义 | 一个包含抽象方法(或不包含)不能实例化的类 | 一种全是抽象方法(或默认实现)的特殊类型 |
关键字 | abstract | interface |
实现方式 | 使用 extends 继承 | 使用 implements 实现 |
二、语法格式
抽象类示例:
public abstract class Animal {String name;public Animal(String name) {this.name = name;}public abstract void makeSound(); // 抽象方法public void eat() {System.out.println(name + " is eating...");}
}
接口示例:
public interface Flyable {void fly(); // 抽象方法default void takeOff() {System.out.println("Taking off...");}
}
三、相同点
- 都不能直接实例化;
- 都可以包含抽象方法;
- 都可以被子类/子接口实现或继承;
- 都支持多态。
四、主要区别(对比表)
比较维度 | 抽象类 | 接口 |
---|---|---|
语法关键字 | abstract class | interface |
实现关键字 | 子类用 extends 继承 | 实现类用 implements 实现 |
多继承支持 | 不支持多继承(单继承限制) | 支持多个接口同时实现 |
成员变量 | 可有字段、构造器,可有静态/实例变量 | 只能定义 public static final 常量(默认) |
构造函数 | 可以有构造函数 | 不能有构造函数 |
默认方法实现 | 可以有普通方法(非抽象) | 支持 default 方法(Java 8+) |
抽象方法 | 可有,也可没有 | 所有非默认方法都是抽象方法(除非默认/static) |
可访问修饰符 | public / protected / private / default | 只能是 public (隐式) |
是否可多实现 | 只能单继承 | 可多实现多个接口 |
是否可继承Object | 是类,自动继承 Object 类 | 接口不继承 Object ,只能由类实现 |
设计目标 | 表达“is-a” 关系,抽象通用父类 | 表达“can-do”能力或行为规范 |
五、使用场景比较
使用场景 | 建议使用 |
---|---|
表示一个对象的通用父类型 | 抽象类(继承体系) |
定义一组行为规范或能力 | 接口(行为能力) |
需要共享部分代码实现 | 抽象类 |
需要跨类结构复用规范 | 接口 |
多个类都需要提供某些方法实现 | 接口(可被多个类实现) |
六、接口的多继承 vs 抽象类的单继承
interface A {void a();
}interface B {void b();
}class C implements A, B {public void a() {}public void b() {}
}
abstract class D {}
abstract class E {}
// class F extends D, E {} // 编译错误:抽象类只能单继承
七、JDK 8+ 以后的接口增强
Java 8 后接口支持以下特性:
特性 | 说明 |
---|---|
default 方法 | 接口可有默认实现的方法(非抽象) |
static 方法 | 接口可定义静态工具方法 |
private 方法 | Java 9+ 支持私有方法重用 |
interface Logger {default void log(String msg) {System.out.println("INFO: " + msg);}static void version() {System.out.println("Logger v1.0");}
}
八、实例场景举例
抽象类适用:
abstract class Shape {String color;abstract double area();
}
接口适用:
interface Drawable {void draw();
}interface Printable {void print();
}class Circle implements Drawable, Printable {public void draw() {}public void print() {}
}
九、经典面试问答
Q1:抽象类和接口有什么区别?
- 抽象类用于抽象出共性;接口用于定义一组功能;
- 抽象类只能单继承,接口可多实现;
- 接口更适合行为复用,抽象类更适合结构封装。
Q2:何时使用抽象类?何时使用接口?
- 如果你需要共享代码 + 强结构控制,用抽象类;
- 如果你希望解耦行为 + 支持多实现,用接口。
Q3:可以同时使用抽象类和接口吗?
可以,一个类可以:
abstract class A implements Interface1, Interface2 { }
十、小结
维度 | 抽象类 | 接口 |
---|---|---|
单继承限制 | 是 | 否(可多实现) |
成员结构 | 变量、构造器、抽象/非抽象方法 | 抽象方法、默认方法、常量 |
构造函数 | 支持 | 不支持 |
面向设计思想 | 抽象、模板、父类通用结构 | 行为扩展、能力标准 |
推荐使用场景 | 有共性代码或父类属性 | 横向能力、插件机制、工具协议等 |