嵌入式软件开发中,虽然很多的开发工具已经支持C++的开发,但是因为有时考虑运行效率和编程习惯,还是有很多人喜欢用C来开发嵌入式软件。Miro Samek说:“我在开发现场发现,很多嵌入式软件开发者(绝大多数是电子工程师)都有工作背景而且他们常常不喜欢用C++。”
面向对象编程(OOP)是一种方法,而不依赖于某特定语言。一般认为,OOP只能使用面向对象的语言,如Smalltalk、C++或Java等固有支持OOP的语言。但是,OOP并不依赖于特殊的语言,只要实现了OOP的封装、继承和多态性这三大基本特性,使用非固有支持面向对象的语言,也可以进行面向对象的编程。
面向对象编程方法的三大基本特性是:
封装性---封装数据(属性)与函数(方法)到类中的能力;
继承性---基于已有的类定义新类的能力;
多态性---在运行时具有一致接口的对象相互替换的能力。
虽然这些特性与面向对象语言有关,但几乎可以用任何语言实现面向对象的这三大基本特性,包括C语言和汇编语言等。事实上,不管实现语言为何,任何大的软件系统几乎都会以某种形式使用抽象(封装)、继承或多态性。
1.C语言的封装 1.1 封装的本质在C++中,一个类中包括属性和方法,声明一个类例子如下:
class A { int n; //属性 A(); //构造函数 void function1(int x){...}; //方法 }在C++中,用A生成两个对象a1和a2时,如下:
A a1 = new A(); A a2 = new A();对于非模板类A,在内存中,对所有的对象,方法function1只有一个拷贝,而对每个对象,都有自己独立的一份属性拷贝,也就是有多个属性拷贝,所谓创建一个对象,也就是创建一套属性。
调用a1.function1()和a2.function1()时,每个对象使用自己的属性n1和n2,而方法代码在内存中是同一套。这就相当于调用functin1(n1,x)和function1(n2,x)。
在C语言实现中,把所有的属性放到一个结构中,所有方法中第一个参数用一个指向自己属性结构的一个指针me, 如下:
function1(struct *me, ...);
这个方法对所有对象有用,具体对哪个对象的属性操作,可以用me来区分。
生成两个文件person.h和person.c,定义一个Person结构类型(也就是类名称),把属性放到结构中,方法中的第一个参数me是Person的引用指针。
pers1.2on.h文件:
在头文件中以结构定义类成员属性,声明构造方法和析构方法,声明public方法。
person.c文件:
在.c文件中声明private方法,并实现所有的方法。
app.c中使用Person类:
#include "person.h" /*包含头*/ void main() { String tmp; Person l_ps1; /*创建一个实例,实际就是一个属性*/ Person l_ps2; /*创建另一个实例,实际就是另一个属性*/ Person_Ctor(l_ps1, 30); /*显式调用构造函数*/ Person_setName(l_ps1,"张三"); /*使用其public方法*/ tmp = Person_getName(l_ps1); /*使用其public方法*/ Person_Ctor(l_ps2, 30); /*使用其public方法*/ Person_setName(l_ps2, "李四"); /*使用其public方法*/ tmp = Person_getName(l_ps2); /*使用其public方法*/ } 2.C语言的继承Student继承自Person, 继承类属性结构的第一个参数指向父类属性,这样可以满足Liskov替换原则。
student.h文件:
在头文件中以结构定义类成员属性,并声明构造、析构函数和public方法。