打印
[ARM入门]

嵌入式软件开发的对象在哪?

[复制链接]
1179|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
呐咯密密|  楼主 | 2024-5-29 17:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 呐咯密密 于 2024-5-29 17:53 编辑

1 面向对象编程基础

面向对象编程涉及到三个重要的特性:封装、继承与多态。部分 C 程序员,特别是嵌入式 C 程序员有一种误解,C 语言不是面向对象的编程语言,C++、Java、Python 等更高级的才是,使用 C 语言无法实现面向对象编程。这种误解致使他们没有动力学习一些优秀的面向对象编程方法,例如设计模式、设计原则、软件架构设计等等,进而很难开发出易维护、易部署、易重用、易管理的软件,很难面对项目需求的变更、扩展,很难开发和维护大型的复杂项目。

1.1 对象

面向对象编程,“对象”是整个编程过程的关键。其常见的解释是“数据与函数的组合”。每个对象都是由一组数据(用以描述对象的状态)和一组函数(对象支持的操作,用以描述对象的行为)组成的。对象实现了数据和操作的结合,使数据和操作可以封装于“对象”这个统一体中。

在面向过程编程中,程序设计注重的是“过程”,先做什么,后做什么;在外界看来,整个程序由一系列散乱的数据和函数组合而成。而在面向对象编程中,程序设计注重的是“对象”,在外界看来,整个程序由一系列“对象”块组合而成,数据和函数封装到了对象内部。

1.2 类

对象是有“类型”的,即类。“类”是对一组对象共性的抽象,表示一类对象,而对象是某个类的一个具体化的个例,通常称之为类的实例。对象通常是由数据和函数组成的,相应的类也具有两部分内容:属性(数据的抽象)和方法(对象行为的抽象)。

除了封装属性和操作外,类还具有访问控制的能力,如某些属性和方法是私有的,不能被外界访问。通过访问控制,能够对内部数据提供不同级别的保护,以防止外界意外地改变或使用私有部分。

1. 属性

类具有属性,它是对数据(对象的状态)的抽象。在 C 程序设计时,通常使用结构体类型来表示一个类,相关属性即包含在相应的结构体类型中。例如学生具有属性:姓名、学号、性别、身高、体重等信息,可以使用如下结构体类型表示“学生类”:

struct student
{
    char name[10];   /* 姓名 (假定最长10字符) */
    unsigned int id;  /* 学号 */
    char sex;    /* 性别:'M',男;'F' ,女 */
    float height;   /* 身高 */
    float weight;   /* 体重 */
};

2. 方法

类具有方法,它是对象行为的抽象,在 C 程序中,方法可以看作普通函数,不过其通常有一个特点 ,函数的第一个参数为类型的指针,指向了一个确定的对象,用以表明此次操作针对哪个对象,在方法实现时,即可通过该指针访问到对象中的各个属性。(微信公众号【嵌入式系统】这是C面向对象必须的,类似C++的this)

针对学生对象,为了对外展现学生自身的信息,自我介绍的格式是对外输出一个固定格式的字符串:

"Hi! My name is xxx, I'm a (boy/girl). My school number is xxx. My height is xxxcm and weight is xxxkg . "

其中的 xxx 对应学生实际的信息,基于此,可以为学生类定义并实现一个“自我介绍”的方法:

void student_self_introduction(struct student *p_this)
{
    printf("Hi! My name is %s, I'm a %s. My school number is %d. My height is %fcm and weight is %fkg",
           p_this->name,
           (p_this->sex == 'M') ? "boy" : "girl",
           p_this->id,
           p_this->height,
           p_this->weight);
}

对于外界来讲,调用学生的“自我介绍”方法可以获知学生的全部信息。基于该类的定义,一个简易的应用程序范例详如下:

void main(void)
{
    struct student chengj = {"chengj", 2024001, 'M', 173, 68};
    struct student hehe = {"hehe", 2024002, 'M', 150, 45};
    student_self_introduction(&chengj);
    student_self_introduction(&hehe);
    // ...
}

类中的方法 student_self_introduction 可以作用于任一学生类对象,对于程序员来讲,编写的代码将适用于一组对象,而非特定的某一个对象,提高了代码利用率。

在实际应用中,对比代码《[color=var(--weui-LINK)]嵌入式算法14---数据流与环形队列》,不少程序员都喜欢编写出一堆非常类似的接口,它们仅通过某一个数字后缀(0、1、2……)来区分,如系统使用到 3 个栈,初级程序员可能实现 3 个入栈函数,不良示意代码如下:

//三个栈入栈的不良范例,引以为戒
int push_stack0(int data)
{
    //...
}

int push_stack1(int data)
{
    //...
}

int push_stack2(int data)
{
    //...
}

三个操作可能除了极小部分的差异外,其它处理完全相同,这就是没有面向对象编程的思维,没有定义对象类型的概念,将操作直接针对每个具体对象(栈 0、栈 1、栈 2),而不是一组同类的对象(所有栈对象)。显然,3个栈的特性和行为都基本类似,因而可以定义一个“栈类型”,如此一来,入栈操作将属于栈类型中的一个方法,适用于所有栈对象。例如:

//数据压入栈, p_stack 指向具体的栈对象
int push_stack(stack *p_stack, int data);

//微信公众号:嵌入式系统
//三个栈的入栈操作均可使用同一个方法
push_stack(p_stack0, 1);
push_stack(p_stack1, 2);
push_stack(p_stack2, 3);


使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:苏州澜宭自动化科技嵌入式工程师
简介:本人从事磁编码器研发工作,负责开发2500线增量式磁编码器以及17位、23位绝对值式磁编码器,拥有多年嵌入式开发经验,精通STM32、GD32、N32等多种品牌单片机,熟练使用单片机各种外设。

481

主题

3795

帖子

47

粉丝