基于多态衍生出的两个概念:
- 抽象接口,简称接口
- 依赖反转
抽象接口
概念:
只包含函数指针的类
- OOP中的一种概念,并不是C开发中头文件引出的API
- 描述某一个功能或动作,不涉及任何底层实现细节
- 函数指针表示抽象方法
OOPC中多态实现的核心手段
函数指针
抽象接口的好处:
即使没有实现相应的类也可以基于抽象接口编写应用程序
依赖注入
概念:
向某个对象提供它所需要的其他对象。
示例:
/* 定义抽象栈 */
typedef struct _abstract_stack{
int (*push)(struct _abstract_stack *abs, int val); //出栈方法
int (*pop)(struct _abstract_stack *abs, int *val); //入栈方法
}abstract_stack_t;
typedef struct _stack_normal{
abstract_stack_t super; //继承抽象栈方法
int *stack_buffer; //栈空间
int top; //栈顶指针
int size; //栈的大小
}stack_normal_t;
类型:
-
构建注入
在派生类中的构造函数(初始化函数)中注入需要的对象。
形式:
int class_a_xxx_init (struct class_a_xxx *p_this, ... , struct class_b_xxx something) { // ... 其它操作 p_this->something = something; // 构建注入 // ... 其它操作 }
-
方法注入
通过某个方法注入所依赖的对象。
形式:
电子表应用中单独定义一个方法注入依赖对象。
int elec_watch_itime_set (struct elec_watch *p_this, struct itime *itime) { p_this->itime = itime; return 0; }
初始化时类的所依赖的对象就可以设置为NULL
int elec_watch_init (struct elec_watch *p_this) { p_this->itime = NULL; /* 设置 itime 为无效值,后续通过其它方法注入 */ // ... 其它应用相关的初始化 return 0; }
两种依赖注入方式区别:
构建注入只注入一次(初始化函数调用一次)。方法注入可以注入多次,方便在运行中切换对象
使用构建注入的情况
- 联系非常紧密,必须存在依赖对象才能正常工作
- 依赖对象在初始化就会使用到(派生类的初始化函数中使用到)
- 依赖的对象不会动态改变
使用方法注入的情况
- 与依赖对象联系不是很紧密
- 初始化函数中不会使用
- 运行中可能会动态改变依赖对象