嵌入式设计模式基础--C语言的继承封装与多态

继承,封装和多态是OOP的三大核心特性,它们共同构了面向对象的基础.但嵌入式开发中大量的使用到的却是C语言这种面向过程的语言,那么我们就需要了解如何在C中使用设计模式的思想做功能开发。要了解设计模式,我们就需要先搞清楚 继承,封装和多态在C语言中应该如何体现。

本系列将会使用一个传感器的例子来说明本节内容。

封装

阿光对封装的理解其实就是将对象的属性和方法高度抽象出来,以传感器为例,传感器的属性可以抽象出传感器类型,传感器数据,采样间隔等,方法可以抽象出获取传感器数据的方法以及打印传感器数据的方法等。

有了以上的抽象,我们就可以定义一个基类来表示传感器

复制代码
typedef struct Sensor Sensor;
struct Sensor {
    const char* type; // 传感器类型
    float data; // 传感器数据
    int samplingInterval; // 采样间隔(单位:毫秒)
    void (*readData)(Sensor* sensor); // 读取数据的方法
    void (*printInfo)(Sensor* sensor); // 打印信息的方法
};

创建Sensor对象函数:(基类构造函数)

复制代码
Sensor* Sensor_create(const char* type, int samplingInterval) {
    Sensor* sensor = (Sensor*)malloc(sizeof(Sensor));
    sensor->type = type;
    sensor->samplingInterval = samplingInterval;
    sensor->data = 0.0;
    sensor->readData = Sensor_readData; // 默认读取数据方法
    sensor->printInfo = Sensor_printInfo; // 默认打印信息方法
    return sensor;
}

销毁Sensor对象函数:(基类析构函数)

复制代码
void Sensor_destroy(Sensor* sensor) {
    free(sensor);
}

以上是对基类的封装,通过封装可以使用基类的方法访问数据,杜绝了直接访问数据的情况,可以有效地做到数据安全和保护。同时封装使得类的内部实现细节对外部透明,那么对于类的属性方法的修改不会影响到外部代码实现,更加方便代码的维护和扩展。同时用户也无需关心传感器数据的内部存储和操作细节,只需通过调用方法即可完成功能。

继承

那么我们假设现在有两款传感器(对象),一款是温度传感器,一款湿度传感器;两个传感器都具有基类的所有属性,但是又会有一些差别,比如温度传感器一般会有最高和对低温的限制,同时对于湿度传感器的话我们可以假定一个适宜的湿度范围为人类的舒适区。那么对于两个对象我们可以分别定义两个派生类:

复制代码
// 定义一个派生类 TemperatureSensor,用于表示温度传感器
typedef struct TemperatureSensor TemperatureSensor;
struct TemperatureSensor {
    Sensor sensor; // 继承自 Sensor
    float maxTemp; // 最高温度
    float minTemp; // 最低温度
};

// 同理,可以定义 HumiditySensor 类来表示湿度传感器
typedef struct HumiditySensor HumiditySensor;
struct HumiditySensor {
    Sensor sensor; // 继承自 Sensor
    float comfortLevel; // 舒适度
};

那么同样的对于派生类我们需要定义构造和析构函数,以及操作对象的方法。

复制代码
// 创建 TemperatureSensor 对象的函数
TemperatureSensor* TemperatureSensor_create(int samplingInterval, 
                                           float maxTemp, float minTemp)                   
 // 销毁 TemperatureSensor 对象的函数
void TemperatureSensor_destroy(TemperatureSensor* tempSensor)
// 温度传感器的读取数据方法
void TemperatureSensor_readData(Sensor* sensor)

HumiditySensor* HumiditySensor_create(int samplingInterval, float comfortLevel)
void HumiditySensor_destroy(HumiditySensor* humiditySensor)
void HumiditySensor_readData(Sensor* sensor)

以上便是继承的概念在嵌入式开发中一个例子,不同的传感器对象继承了基类的属性,使得代码具有很好的复用性和扩展性,如果有新增的图像传感器依然可以继承基类的属性且只需要单独定义图像传感器的差异属性,这使得代码各个模块之间相互独立,易于后期维护和扩展。

多态

多态的概念:多态允许对象在继承体系中根据需要动态地表现出不同的行为。通过多态,调用者可以通过一个统一的接口来调用不同对象的具体实现,而无需关心对象的实际类型。

即我们可以通过基类指针调用不同派生类的方法。用到上面的例子中我们就可以这样理解:在一个接口内部,可以通过基类Sensor指针来调用温度和湿度传感器的方法。

复制代码
int main() {
    // 创建不同类型的传感器对象
    Sensor* sensors[2];
    sensors[0] = (Sensor*)TemperatureSensor_create(1000, 45.0, 15.0);
    sensors[1] = (Sensor*)HumiditySensor_create(2000, 60.0);
    // 多态调用,读取数据并打印信息
    for (int i = 0; i < 2; i++) {
        sensors[i]->readData(sensors[i]);
        sensors[i]->printInfo(sensors[i]);
    }
    // 销毁对象
    TemperatureSensor_destroy((TemperatureSensor*)sensors[0]);
    HumiditySensor_destroy((HumiditySensor*)sensors[1]);
    return0;
}

以上便是C语言中模拟面向对象中多态的特性,多态使得不同的对象可以使用同一接口实现不同的行为,调用者不需要知道对象的具体类型,只需要知道调用对象的方法即可。做到了各个模块之间解耦。

总结

面向对象的变成模型是设计模式的基础,这种思想将具体的系统分解为独立的对象或类,每个对象负责特定的功能。这种模块化的思想会使得代码的功能更加清晰和易于维护。在后续的简单工厂模式,策略模式等等设计模式中都有很好的体现,这对于嵌入式应用或者驱动开发来说,都是很好的实践。

相关推荐
ZC跨境爬虫4 小时前
LeetCode 13. 罗马数字转整数(多解法详解 + Java Python 实现)
java·python·leetcode
省长4 小时前
Sa-Token v1.46.0 发布 🚀,来看看有没有令你心动的功能!
java·后端·开源
j7~4 小时前
【C语言】《C语言函数递归完全指南:思想、限制、经典例题(阶乘/斐波那契/青蛙跳台阶/汉诺塔)与迭代优化》
c语言·函数递归·汉诺塔问题·青蛙跳台阶问题·递归与迭代·n的阶乘
LayZhangStrive4 小时前
融360 一面
java·面试·后端开发
城管不管5 小时前
重生——第十次面试之开源中国一面挂
java·linux·开发语言·算法·面试·职场和发展·开源
Java小白笔记5 小时前
Windows系统免软件命令激活
java·网络·人工智能·windows·ai·ai编程
爱敲键盘的猴子5 小时前
深入理解 Java HashMap
java·hashmap
霸道流氓气质5 小时前
Java开发者AI编程常用MCP、Skills、Rules全景汇总
java·开发语言·ai编程
天涯醉青楼5 小时前
Spring Boot 接口返回 Bean 时字段名“变形”的深度剖析与解决方案
java
YSL0701245 小时前
动态内存管理
c语言