Java抽象类与接口详解
一、抽象类(Abstract Class)
1. 定义与基本使用
// 抽象类定义
public abstract class Animal {// 抽象方法(无实现)public abstract void makeSound();// 具体方法(有实现)public void sleep() {System.out.println("动物在睡觉");}
}// 继承抽象类
class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("汪汪汪");}
}
2. 抽象类特点
- 用
abstract
关键字修饰 - 可以包含抽象方法和具体方法
- 不能直接实例化
- 子类必须实现所有抽象方法(除非子类也是抽象类)
3. 适用场景
- 多个相关类共享代码和行为的场景
- 需要定义非静态或非final字段时
- 需要定义构造方法时
- 需要控制子类访问权限时
二、接口(Interface)
1. 定义与基本使用
// 接口定义(Java 8+)
public interface Vehicle {// 抽象方法(默认public abstract)void start();// 默认方法(Java 8+)default void stop() {System.out.println("车辆停止");}// 静态方法(Java 8+)static void honk() {System.out.println("按喇叭!");}
}// 实现接口
class Car implements Vehicle {@Overridepublic void start() {System.out.println("汽车启动");}
}
2. 接口特点
- 所有方法默认
public abstract
(Java 8前) - 可以包含
default
方法和static
方法(Java 8+) - 可以定义常量(默认
public static final
) - 支持多实现(一个类可实现多个接口)
3. 适用场景
- 定义行为契约/规范
- 需要多继承行为的场景
- 定义回调机制(如事件监听)
- 作为API的契约定义
三、抽象类与接口对比
特性 | 抽象类 | 接口 |
---|---|---|
关键字 | abstract class | interface |
方法 | 可含抽象方法和具体方法 | Java 8前只能有抽象方法,之后可含默认/静态方法 |
变量 | 可含任意类型变量 | 只能含public static final 常量 |
构造器 | 有 | 无 |
继承 | 单继承 | 多实现 |
访问修饰符 | 可任意 | 默认public |
设计目的 | 代码复用 | 定义契约 |
实例化 | 不能 | 不能(但可用匿名类或Lambda) |
四、如何选择
使用抽象类当:
- 多个相关类需要共享代码
- 需要定义非final的字段
- 需要定义非public的成员
- 需要定义构造方法
使用接口当:
- 需要定义行为规范
- 需要多继承行为
- 需要定义API契约
- 需要支持Lambda表达式
五、Java 8+的新变化
-
接口的默认方法:
interface Flyable {default void fly() {System.out.println("默认飞行方式");} }
-
接口的静态方法:
interface MathUtils {static int add(int a, int b) {return a + b;} }
-
私有方法(Java 9+):
interface Logger {private void log(String message) {System.out.println(message);}default void info(String msg) {log("INFO: " + msg);} }
六、设计建议
- 优先使用接口:更灵活,更容易扩展
- 接口定义行为,抽象类实现部分行为
- 组合优于继承:考虑使用接口+组合代替复杂的类继承
- 接口隔离原则:将大接口拆分为多个小接口
七、典型应用示例
1. 抽象类应用:模板方法模式
abstract class Game {abstract void initialize();abstract void startPlay();abstract void endPlay();// 模板方法public final void play() {initialize();startPlay();endPlay();}
}class Cricket extends Game {// 实现各个步骤...
}
2. 接口应用:策略模式
interface PaymentStrategy {void pay(int amount);
}class CreditCardPayment implements PaymentStrategy {public void pay(int amount) {System.out.println("信用卡支付: " + amount);}
}class ShoppingCart {private PaymentStrategy strategy;public void setStrategy(PaymentStrategy strategy) {this.strategy = strategy;}public void checkout(int amount) {strategy.pay(amount);}
}