面向对象高级特性(抽象类、接口)
学习目标:
-
理解抽象类与接口的核心概念及区别
-
掌握抽象类和接口的定义与实现方法
-
能够合理选择抽象类或接口设计程序结构
-
结合实际场景应用多态与解耦
一、课程引入
1.1 为什么需要抽象类与接口?
-
抽象类:抽取多个类的共性(如动物都有
eat()
方法,但实现不同) -
接口:定义行为规范(如USB设备必须实现
connect()
方法) -
设计目标:
-
提高代码复用性(抽象类)
-
实现多继承效果(接口)
-
1.2 核心对比
特性 | 抽象类 | 接口(Java 8+) |
---|---|---|
定义方法 | 可包含抽象/具体方法 | 默认只含抽象方法(可含默认方法) |
变量 | 可包含成员变量 | 只能包含常量(public static final ) |
继承/实现 | 单继承 | 多实现 |
设计目标 | “是什么”(is-a关系) | “能做什么”(has-a关系) |
二、抽象类
2.1 抽象类的定义
语法
public abstract class 类名 {
// 抽象方法(无方法体)
public abstract void 方法名();
// 具体方法
public void 方法名() { ... }
}
案例1:图形类抽象
public abstract class Shape {
// 抽象方法:计算面积
public abstract double calculateArea();
// 具体方法:公共逻辑
public void printInfo() {
System.out.println("这是一个图形");
}
}
// 子类必须实现抽象方法
public class Circle extends Shape {
private double radius;
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
2.2 抽象类的应用场景
-
场景:多个子类有共同属性和方法,但部分行为需要不同实现
-
JDK示例:
InputStream
是抽象类,FileInputStream
是其子类
三、接口
3.1 接口的定义与实现
语法(Java 8+)
public interface 接口名 {
// 常量
String TYPE = "USB";
// 抽象方法(默认public abstract)
void connect();
// 默认方法(Java 8+)
default void check() {
System.out.println("接口自检完成");
}
// 静态方法(Java 8+)
static void printVersion() {
System.out.println("接口版本1.0");
}
}
案例2:设备连接接口
public interface USBDevice {
void connect();
void disconnect();
}
// 实现类
public class Mouse implements USBDevice {
@Override
public void connect() {
System.out.println("鼠标已连接");
}
@Override
public void disconnect() {
System.out.println("鼠标已断开");
}
}
3.2 接口的多实现
案例3:智能手机功能
public interface Camera {
void takePhoto();
}
public interface GPS {
void locate();
}
// 类可实现多个接口
public class SmartPhone implements Camera, GPS {
@Override
public void takePhoto() { ... }
@Override
public void locate() { ... }
}
四、综合应用与设计模式
4.1 综合案例:门与报警系统
// 接口定义能力
public interface Alarm {
void alarm();
}
// 抽象类定义共性
public abstract class Door {
public abstract void open();
public abstract void close();
}
// 具体类组合功能
public class SecurityDoor extends Door implements Alarm {
@Override
public void open() {
System.out.println("门已打开");
}
@Override
public void close() {
System.out.println("门已关闭");
}
@Override
public void alarm() {
System.out.println("触发警报!");
}
}
4.2 面向接口编程的优势
-
解耦:调用方依赖接口而非具体实现
-
扩展性:新增实现类无需修改现有代码
五、常见错误与最佳实践
5.1 常见错误
-
错误1:试图实例化抽象类或接口
Shape shape = new Shape(); // 编译错误 USBDevice device = new USBDevice(); // 编译错误
错误2:接口默认方法冲突
interface A { default void foo() {} }
interface B { default void foo() {} }
class C implements A, B {} // 编译报错,需重写foo()
5.2 设计原则
-
优先使用接口:需要多继承或定义行为规范时
-
合理使用抽象类:存在多个子类共享代码时
六、总结与练习
6.1 总结
-
抽象类:抽取共性,包含实现细节
-
接口:定义规范,支持多态扩展
-
核心区别:单继承 vs 多实现,状态 vs 行为
6.2 课后任务
-
设计一个“支付系统”,定义
Payment
接口(含pay()
方法),实现Alipay
和WechatPay
类 -
用抽象类实现“车辆管理系统”(如抽象类
Vehicle
,子类Car
、Bike
) -
预习下一节课:内部类与枚举
6.3 扩展挑战
-
阅读JDK源码(如
List
接口与AbstractList
抽象类),分析其设计思想