- 抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。
- 用科学抽象的方法来透过事物的现象获得它的本质,并用概念、原理、规律的形式描述它。
1、抽象的概述(抽象(Abstraction)-- 通用的设计思想)
- 在编程中,抽象是提取对象的核心特性,忽略具体实现细节 ,只暴露必要的高层接口。
- 通过 抽象类(abstract class) 或 接口(interface) 定义规范,强制子类实现抽象方法 。
- 抽象的核心:
- 简化 复杂性,让调用者关注“做什么”(功能),而非“怎么做”(实现)。
abstract class Game {
abstract void initialize();
abstract void startPlay();
public final void play() {
initialize();
startPlay();
}
}
class Cricket extends Game {
@Override
void initialize() { System.out.println("初始化板球游戏"); }
@Override
void startPlay() { System.out.println("开始玩板球"); }
}
2、高度抽象所需的支持
- 借助编程语言提供的接口类或抽象类这两种语法机制,来实现高度抽象这一特性。
- 接口类:如 Java 中的 interface 关键字 语法。
- 抽象类:如 Java 中的 abstract 关键字 语法。
3、抽象的应用场景
- 抽象是一种只关注功能点不关注实现细节的设计思路,能帮大脑过滤掉许多非必要的信息。
- 抽象作为一种的设计思想,在代码设计中,起到非常重要的指导作用。如:很多设计原则。
- 在定义 / 命名类的方法时,也要有抽象思维,不要在方法定义中,暴露太多的实现细节,以保证在某个时间点需要改变方法的实现逻辑时,不用去修改其定义。
- 如: getAliyunPictureUrl() 就不是一个具有抽象思维的命名。
- 因为,某一天不再把图片存储在阿里云上,而是存储在私有云上,那这个命名也要随之被修改 。
- 如果定义一个比较抽象的函数。
- 如: getPictureUrl(),那即便内部存储方式修改了,也不需要修改命名 。
4、封装 vs 抽象
维度 | 封装(Encapsulation) | 抽象(Abstraction) |
---|
核心思想 | 保护数据安全,隐藏实现细节 | 简化复杂性,定义高层规范 |
实现手段 | 访问修饰符( private / public ) + getter/setter | 抽象类/接口 + 抽象方法 |
关注内容 | 数据(属性)的存储和访问控制 | 行为(方法)的定义与实现分离 |
代码示例 | 类的私有属性 + 公有方法 | 抽象方法的声明 + 子类的具体实现 |
修改影响 | 修改属性类型或校验逻辑需调整 getter/setter | 修改抽象方法的参数或返回值会影响所有子类 |
5、封装 和 抽象 通常结合使用,共同构建 健壮的 面向对象系统:
- 抽象:
- Payment 接口定义了支付行为的规范。
- 隐藏了具体支付方式(如:信用卡、支付宝)的实现细节。
- 封装:
- CreditCardPayment 类封装了卡号(private 属性)。
- 避免外部直接访问,同时实现了 pay() 方法的具体逻辑。
interface Payment {
void pay(double amount);
}
class CreditCardPayment implements Payment {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(double amount) {
System.out.println("信用卡支付 " + amount + " 元,卡号:" + cardNumber);
}
}