未命名 1
分类:4-全栈/01-elysia
发布于:
阅读时间:10 分钟
在软件架构设计中,理解**接口(Interface)和抽象类(Abstract Class)**的区别是消除代码混乱的关键。结合你当前的项目结构(
AbstractStorageBunS3Storage1. 抽象类 vs 接口:本质区别
| 特性 | 接口 (Interface) | 抽象类 (Abstract Class) |
|---|---|---|
| 本质意义 | 能力的定义(能做什么)。它是一份契约,规定了外部调用的标准。 | 事物的抽象(是什么)。它是多个具体子类的共性提取。 |
| 代码复用 | 不能包含逻辑。只能定义方法名、参数和返回值(在 TS 中)。 | 可以包含逻辑。可以编写通用的代码供子类直接使用。 |
| 成员变量 | 不能定义实例变量(只能定义类型)。 | 可以定义并存储状态(如 |
| 多继承 | 一个类可以实现多个接口。 | 一个类只能继承一个抽象类。 |
2. 哪些是“实现”,哪些是“继承”?
在你的代码库中,这两个概念分别对应以下结构:
继承 (Inheritance / Extends)
“继承”用于子类与父类之间。 当你希望子类自动拥有父类已经写好的方法时,使用继承。
-
代码体现:使用关键字
。extends -
你的项目示例:
-
继承了
BunS3Storage。AbstractImageStorage -
继承了
OSSStorage。AbstractStorage -
含义:
是BunS3Storage的一种,它自动获得了父类中AbstractImageStorage和generateUniqueFileName等已经写好的通用工具方法。validateFileSize
-
实现 (Implementation / Implements)
“实现”用于类与接口之间。 当你定义了一个标准,要求不同的类必须按照这个标准提供功能时,使用实现。
-
代码体现:使用关键字
(虽然在你目前的 TS 代码中多采用直接继承抽象类的方式)。implements -
你的项目示例(如果你采用了
方案):IStorage-
实现了
BunS3StorageImpl接口。IStorage -
含义:
规定了必须有IStorage方法,upload保证提供这个方法的具体代码。BunS3StorageImpl
-
3. 在你项目中的实际应用建议
你之前的代码之所以感觉“混乱”,是因为你在继承关系上做了重复:
-
抽象类(继承的源头):
-
提供了基础的文件处理逻辑,如
AbstractStorage。processFileData -
也提供了类似的逻辑,如
AbstractImageStorage。generateUniqueFileName -
建议:保留一个
即可。AbstractStorage
-
-
具体类(实现者/继承者):
-
和
BunS3Storage应该直接继承自唯一的抽象类LocalStorage。AbstractStorage -
它们通过重写(Override)父类的抽象方法(如
)来提供具体实现。uploadFile
-
总结
-
如果你想定义标准(比如:所有存储插件都必须有上传和删除功能),用接口或抽象类中的抽象方法。
-
如果你想少写重复代码(比如:阿里云和本地存储都要生成随机文件名),把这段代码写在抽象类里,让子类去继承它。
在现代 TypeScript 开发中,通常直接使用一个抽象类作为顶层设计(如你的
AbstractStorage