C语言实现面向对象的编程思想
面向对象编程是一种编程思想,并不是那个特定的语言或工具独有的。面向对象的三大基本特征:封装、继承和多态。因此利用C语言也可以实现面向对象的编程。
1.封装
封装的基本思想就是隐藏对象的属性和实现细节,仅对外提供公开的访问接
口,将数据与操作数据的源代码进行有机结合,把数据和操作数据的方法打包到一个类里面。原则为:将不需要对外提供的内容隐藏起来;把属性隐藏,提供公共方法对其访问。例如Linux下的文件指令fclose、fread、fopen、fseek函数对应为文件的操作函数,对象就是FIFE。将数据和操作数据的方法(函数)封装为一个整体,形成独立性很强的模块,将对象的设计者和对象的使用者隔离,使用者不必了解对象内部具体的实现细节,而只需要通过对象提供的外部接口来访问该对象。比如汽车的属性有轮胎、方向盘、发动机、变速箱等;行为(功能)有直线行驶、左转、右转行驶等。
C语言可以利用结构体+函数指针+static的方法实现C++中类的方法,C语言结构体定义成员变量将数据进行封装,同时使用函数指针实现对对象行为的封装,static将对象的行为限制在本模块内使用。下面将通过两个例子说明利用C语言的结构体和函数指针的方法实现对对象的封装。
示例:
以创建人这个对象作为示例说明面向对象的编程思想。
person.h文件
#ifndef PERSON_H_
#define PERSON_H_
typedef struct PersonObjectDef_
{
char* name;
char* sex;
int age;
float weight;
float height;
void (*pf_SetSex) (struct PersonObjectDef_* pdI_Person, const char* sex);
void (*pf_SetAge) (struct PersonObjectDef_* pdI_Person, int age);
void (*pf_SetWeight)(struct PersonObjectDef_* pdI_Person, float weight);
void (*pf_SetHeight)(struct PersonObjectDef_* pdI_Person, float height);
}PersonObjectDef;
/*创建对象*/
PersonObjectDef* pub_CreatePerson(const char* psI_name);
/*删除对象*/
void pub_DeletePerson(PersonObjectDef* pdI_Person);
#endif
person.c文件
#include
#include
#include
#include "person.h"
/*设置性别*/
static void prv_SetPersonSex(struct PersonObjectDef_* pdI_Person,
const char* pcsI_Sex)
{
if (NULL != pdI_Person)
{
pdI_Person->sex = (char*)malloc(strlen(pcsI_Sex) + 1); /*分配内存*/
if (NULL != pdI_Person->sex)
{
strcpy(pdI_Person->sex, pcsI_Sex);
}
}
}
/*设置年龄*/
static void prv_SetPersonAge(struct PersonObjectDef_* pdI_Person, int age)
{
if (NULL != pdI_Person)
{
pdI_Person->age = age;
}
}
/*设置体重*/
static void prv_SetPersonWeight(struct PersonObjectDef_* pdI_Person,
float f32I_Weight)
{
if (NULL != pdI_Person)
{
pdI_Person->weight = f32I_Weight;
}
}
/*设置身高*/
static void prv_SetPersonHeight(struct PersonObjectDef_* pdI_Person,
float f32I_Height)
{
if (NULL != pdI_Person)
{
pdI_Person->height = f32I_Height;
}
}
/*创建对象*/
PersonObjectDef* pub_CreatePerson(const char* pcsI_name)
{
PersonObjectDef* pdT_Person = NULL;
/*为对象分配内存空间*/
pdT_Person = (PersonObjectDef*)malloc(sizeof(PersonObjectDef));
if (NULL == pdT_Person) /*内存分配失败*/
{
return NULL;
}
else
{
memset(pdT_Person, 0, sizeof(PersonObjectDef)); /*将分配的内存清0*/
pdT_Person->name = (char*)malloc(strlen(pcsI_name) + 1); /*为姓名分配内存*/
strcpy(pdT_Person->name, pcsI_name);
pdT_Person->pf_SetSex = prv_SetPersonSex;
pdT_Person->pf_SetAge = prv_SetPersonAge;
pdT_Person->pf_SetWeight = prv_SetPersonWeight;
pdT_Person->pf_SetHeight = prv_SetPersonHeight;
return pdT_Person;
}
}
/*删除对象*/
void pub_DeletePerson(PersonObjectDef* pdI_Person)
{
if (NULL == pdI_Person)
{
return;
}
if (NULL != pdI_Person->name)
{
free(pdI_Person->name);
}
if (NULL != pdI_Person->sex)
{
free(pdI_Person->sex);
}
free(pdI_Person);
}
main.c文件如下:
#include
#include
#include
#include "person.h"
int main(void)
{
PersonObjectDef* pdT_Person = NULL;
pdT_Person = pub_CreatePerson("李磊");
if(NULL != pdT_Person)
{
pdT_Person->pf_SetSex(pdT_Person,"男");
pdT_Person->pf_SetAge(pdT_Person,23);
pdT_Person->pf_SetHeight(pdT_Person,1.789);
pdT_Person->pf_SetWeight(pdT_Person,98.7697);
printf("This Person name is: %s\n",pdT_Person->name);
printf("This Person sex is: %s\n",pdT_Person->sex);
printf("This Person age is: %d\n",pdT_Person->age);
printf("This Person height is: %f\n",pdT_Person->height);
printf("This Person weight is: %f\n",pdT_Person->weight);
pub_DeletePerson(pdT_Person);
getchar();
return 0;
}
}
程序运行结果如下:
2.继承
继承就是子类继承父类的特征和行为,使得子类对象具有父类的实例域和方
法,使得子类具有父类相同的行为。换句话讲,继承就是子类拥有父类的数据、方法同时又增添了自己的东西。继承实际上就是对父类的扩展,为了能够实现兼容,子类必须有父类的所有变量和函数,然后可以在其基础上增加一些功能,也可以改变原有的功能。子类继承父类,可以直接享受父类中已经封装好的属性和方法;同时应根据自己的独有的特征,封装子类特有的属性和方法。C语言可以利用结构体包含的扩展实现继承关系。上面的例子我们实现了一个person的对象,下面我们由person这个对象派生出teacher这个子类。同时还可以由person这个类派生出student、doctor、pilot、captain等子类。
teacher.h文件如下:
#ifndef TEACHER_H_
#define TTACHER_H_
#include "person.h"
#ifdef __cplusplus
/*表示是C语言的头文件*/
extern "C"
{
#endif
typedef struct TeacherObjectDef_
{
PersonObjectDef* Person;
int Salary;
char* TeacherNum;
char* Subject;
void (*pf_SetSalary) (struct TeacherObjectDef_* pdI_Teacher,int Salary);
void (*pf_SetNum) (struct TeacherObjectDef_* pdI_Teacher,char* num);
void (*pf_SetSubject)(struct TeacherObjectDef_* pdI_Teacher,char* subject);
}TeacherObjectDef;
TeacherObjectDef* pub_CreateTeacher(const char* pcu8I_name);
void pub_DeleteTeacher(TeacherObjectDef* pdI_Teacher);
#ifdef __cplusplus
}
#endif
#endif
teacher.c文件如下:
#include
#include
#include
#include "person.h"
#include "teacher.h"
/*设置薪资*/
static void prv_SetTeacherSalary(struct TeacherObjectDef_* pdI_Teacher,
int u16I_Salary)
{
if (NULL != pdI_Teacher)
{
pdI_Teacher->Salary = u16I_Salary;
}
}
/*设置学科*/
static void prv_SetTeacherSubject(struct TeacherObjectDef_* pdI_Teacher,
char* psI_Subject)
{
if (NULL != pdI_Teacher)
{
pdI_Teacher->Subject = (char*)malloc(strlen(psI_Subject) + 1);
strcpy(pdI_Teacher->Subject, psI_Subject);
}
}
/*设置工号*/
static void prv_SetTeacherNum(struct TeacherObjectDef_* pdI_Teacher,
char* psI_Num)
{
if (NULL != pdI_Teacher)
{
pdI_Teacher->TeacherNum = (char*)malloc(strlen(psI_Num)+1);
strcpy(pdI_Teacher->TeacherNum, psI_Num);
}
}
/*创建对象*/
TeacherObjectDef* pub_CreateTeacher(const char* pcu8I_name)
{
TeacherObjectDef* pdT_Teacher = NULL;
/*为对象分配内存*/
pdT_Teacher = (TeacherObjectDef*)malloc(sizeof(TeacherObjectDef));
if (NULL == pdT_Teacher)
{
return NULL;
}
else
{
memset(pdT_Teacher,0,sizeof(TeacherObjectDef));
pdT_Teacher->Person = pub_CreatePerson(pcu8I_name);
pdT_Teacher->pf_SetNum = prv_SetTeacherNum;
pdT_Teacher->pf_SetSalary = prv_SetTeacherSalary;
pdT_Teacher->pf_SetSubject = prv_SetTeacherSubject;
return pdT_Teacher;
}
}
/*删除对象*/
void pub_DeleteTeacher(TeacherObjectDef* pdI_Teacher)
{
if (NULL == pdI_Teacher)
{
return;
}
if (NULL != pdI_Teacher->Person)
{
free(pdI_Teacher->Person);
}
free(pdI_Teacher);
}
main.c文件如下:
#include
#include
#include
#include "person.h"
#include "teacher.h"
int main(void)
{
TeacherObjectDef* pdT_Teacher = NULL;
pdT_Teacher = pub_CreateTeacher("李明");
if (NULL != pdT_Teacher)
{
pdT_Teacher->Person->pf_SetAge(pdT_Teacher->Person,32);
pdT_Teacher->Person->pf_SetHeight(pdT_Teacher->Person,1.789);
pdT_Teacher->Person->pf_SetSex(pdT_Teacher->Person,"男");
pdT_Teacher->Person->pf_SetWeight(pdT_Teacher->Person,97.5678);
pdT_Teacher->pf_SetNum(pdT_Teacher,"H024146");
pdT_Teacher->pf_SetSalary(pdT_Teacher,12000);
pdT_Teacher->pf_SetSubject(pdT_Teacher,"地理");
}
printf("This teacher name is: %s\n", pdT_Teacher->Person->name);
printf("This teacher sex is: %s\n", pdT_Teacher->Person->sex);
printf("This teacher age is: %d\n", pdT_Teacher->Person->age);
printf("This teacher weight is: %f\n", pdT_Teacher->Person->weight);
printf("This teacher height is: %f\n", pdT_Teacher->Person->height);
printf("This teacher number is: %s\n", pdT_Teacher->TeacherNum);
printf("This teacher salary is: %d\n", pdT_Teacher->Salary);
printf("This teacher subject is: %s\n", pdT_Teacher->Subject);
pub_DeleteTeacher(pdT_Teacher);
getchar();
return 0;
}
程序运行结果如下:
3.多态
多态是指同一个行为具有多个不同的表现形式,具体的就是指一个对象的相
同方法在不同情形有不同的表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。同一个消息为不同的对象接收时可产生完全不同的行为。可以利用c语言的void*来实现多态。