目录
[3.1 抽象类代码演示](#3.1 抽象类代码演示)
[3.2 接口代码演示(兼容 JDK8+ 全特性)](#3.2 接口代码演示(兼容 JDK8+ 全特性))
[3.3 单继承 vs 多实现 核心区别演示](#3.3 单继承 vs 多实现 核心区别演示)
[5.1 优先使用接口的场景](#5.1 优先使用接口的场景)
[5.2 优先使用抽象类的场景](#5.2 优先使用抽象类的场景)
在 Java 面向对象进阶体系中,抽象类(Abstract Class) 和**接口(Interface)**都是用来定义"规范、模板、行为",都无法直接实例化,都可以包含抽象方法。
但二者在 继承机制、成员变量、方法权限、构造方法、设计思想、业务场景 上有着本质区别,是 Java 面试最高频、也是架构设计最核心的考点。
很多开发者工作多年依然分不清什么时候用抽象类、什么时候用接口。本文结合 JDK8、JDK9 新版本特性、完整可运行代码、实战场景,彻底吃透二者区别。
一、核心概念简述
抽象类 :是对事物本身的抽象,抽取同类对象的公共属性和公共行为,用于模板复用、代码复用。
接口 :是对行为能力的抽象,定义一套行为规范,只规定"能做什么",不关心"怎么做",用于解耦、多态、规范约束。
二、接口与抽象类全方位对比表(面试必背)
| 对比维度 | 接口(Interface) | 抽象类(Abstract Class) |
|---|---|---|
| 继承实现机制 | 多实现:一个类可以 implement 多个接口 | 单继承:一个类只能 extends 一个抽象类 |
| 成员变量 | 只能是 public static final 常量(不可修改) | 普通变量、静态变量、常量都可以定义 |
| 成员方法 | JDK8前:仅抽象方法JDK8+:抽象方法 + default默认方法 + static静态方法JDK9+:新增 private 私有方法 | 任意组合:抽象方法、普通实例方法、静态方法、私有方法 |
| 构造方法 | 无构造方法 | 有构造方法(供子类 super 调用,自身不能实例化) |
| 设计思想 | 行为规范、能力约束、模块解耦 | 模板抽取、公共代码复用、统一父类结构 |
| 典型案例 | Runnable、List、Serializable | HttpServlet、AbstractList、AbstractMap |
三、核心特性代码实战演示
3.1 抽象类代码演示
抽象类可以拥有普通属性、常量、抽象方法、普通方法、构造方法,支持单继承。
java
// 抽象类
abstract class Animal {
// 普通成员变量
public String name;
// 常量
public static final String TYPE = "动物";
// 构造方法:供子类调用
public Animal(String name) {
this.name = name;
}
// 抽象方法:子类必须实现
public abstract void cry();
// 普通方法:代码复用
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
// 子类继承抽象类(只能单继承)
class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void cry() {
System.out.println(name + ":喵喵喵");
}
}
public class AbstractTest {
public static void main(String[] args) {
Cat cat = new Cat("小猫");
cat.cry();
cat.sleep();
}
}
特点 :抽象类重在模板复用,子类可以直接复用父类普通方法。
3.2 接口代码演示(兼容 JDK8+ 全特性)
接口只能是常量,拥有抽象方法、默认方法、静态方法、私有方法,支持多实现。
java
// 定义行为接口
interface Runable {
// 默认:public static final 常量
String DESC = "奔跑能力";
// 抽象方法(必须被实现)
void run();
// JDK8 默认方法:有默认实现,子类可重写可不重写
default void info() {
System.out.println("具备奔跑能力");
}
// JDK8 静态方法:接口直接调用
static void staticMethod() {
System.out.println("接口静态方法");
}
// JDK9 私有方法:内部复用,对外隐藏
private void privateMethod() {
System.out.println("接口私有方法");
}
}
// 多实现:一个类可以实现多个接口
interface Swimable{}
class Dog implements Runable, Swimable {
@Override
public void run() {
System.out.println("小狗快速奔跑");
}
}
public class InterfaceTest {
public static void main(String[] args) {
Dog dog = new Dog();
dog.run();
dog.info();
Runable.staticMethod();
}
}
特点 :接口重在行为规范,只定义能力,不强制复用代码。
3.3 单继承 vs 多实现 核心区别演示
java
// 抽象类只能单继承
// class A extends Animal, Cat {} 编译报错
// 接口可以多实现
class Test implements Runable, Swimable {}
四、变量权限核心坑点实战
接口变量默认全部是常量,无法二次赋值;抽象类变量可自由修改。
java
interface TestInterface{
String MSG = "hello"; // 默认 public static final
}
abstract class TestAbstract{
public String msg = "hello";
}
public class VarTest {
public static void main(String[] args) {
// TestInterface.MSG = "test"; 编译报错:常量不可修改
TestAbstract a = new TestAbstract(){};
a.msg = "test"; // 正常修改
System.out.println(a.msg);
}
}
五、业务场景选型(开发必看)
5.1 优先使用接口的场景
-
用于定义 行为规范、能力标准;
-
不同类、无继承关系的类,拥有相同行为(Runnable、序列化、读写能力);
-
需要 多实现、解耦、拓展 的场景;
-
日常架构设计:面向接口编程、屏蔽实现细节。
5.2 优先使用抽象类的场景
-
多个子类属于同一类事物,存在大量公共代码;
-
需要抽取公共字段、公共逻辑、统一模板;
-
需要控制子类模板流程(模板方法模式);
-
需要定义构造方法、成员变量的场景。
六、面试极简背诵总结
1. 继承区别:抽象类单继承,接口多实现;
2. 变量区别:接口只有常量,抽象类支持任意变量;
3. 方法区别:接口 JDK8/9 迭代新增默认、静态、私有方法,抽象类方法无限制;
4. 构造方法:接口无构造方法,抽象类有构造方法;
5. 设计思想:抽象类做模板复用,接口做行为规范和解耦。
七、文末小结
抽象类和接口的本质区别:抽象类是"是什么"(归属模板),接口是"能什么"(行为能力)。
日常开发遵循:尽量使用接口解耦,公共代码复用使用抽象类。吃透二者区别,不仅能搞定面试,更是掌握面向对象设计、模板模式、接口隔离原则的核心基础。