知识讲解
介绍多态
多态是指对于同一个消息,不同的类对象会做出不同的反应。
在面向对象语言中(java)中,多态与继承通常是一起使用的。通常是让父类对象引用其子类对象,而多态就体现在方法调用时,父类会根据实际引用对象的类型来确定最终使用某个类的方法。
比如:Student类继承了Person类,而在实际调用时,会判断当前类的数据类型,最终执行Person对象买票全价,Student对象买票半价。
oopc中使用接口实现多态
oopc中使用接口实现多态,本质上也是结构体的合理利用。(这里小编就不过多赘述了,如果大家有兴趣可以去看看小编的这篇文章 lw_oopc框架中接口讲解)
本次是需要实现:使用类shape继承circle类、square类,最后再使用shape实现多态。(这里需要说明java中没有多继承)
在本次基于oopc进行面向对象开发时,由于一个类是无法直接继承另外两个类的,因此这里使用用接口INTERFACE
来实现多继承。
这也就是说,shape类是直接"继承"了接口baseShape的,而具体的多态体现只有等到调用接口baseShape时才能够具体体现,例如:当我们接口中的函数vGetValueByname()
时,就会根据类的名字返回值。实现框架图大家可以看看下图:
在接口实现的多继承中,从存储上来看,不同的类是使用数组存储的,也就是说,每次调用某一个类时,还需要遍历数组,查找这个类的存储位置。如下图就是一个存储示例:
与常见的面向对象语言一样(java),oopc框架下,参与多态的各个类也是需要实现各自的方法,例如:
圆类实现计算面积:
// 计算面积
static float cGetArea(void*p)
{
circle*pthis = (circle*)p;
return 3.14*pthis->baseShape.value*pthis->baseShape.value;
}
正方形类实现计算面积:
// 计算面积
static float sGetArea(void*p)
{
square*pthis = (square*)p;
return pthis->baseShape.value*pthis->baseShape.value;
}
当然了,实现某个具体的方法后,还需要使用 构造器CTOR
或 自己初始化 将其加入到类中。
函数示例
测试使用的main函数:
int main(void)
{
// 形状类
shape*sh = (shape*)shape_new();
sh->vInit(sh,10);
// 圆类1
circle*c1 = (circle*)circle_new();
c1->baseShape.vInit(c1,"circle 1",2);
// 添加存储
sh->vAddShape(sh,c1);
// 圆类2
circle*c2 = (circle*)circle_new();
c2->baseShape.vInit(c2,"circle 2",3);
// 添加存储
sh->vAddShape(sh,c2);
// 正方形类1
square*s1 = (square*)square_new();
s1->baseShape.vInit(s1,"square 1",4);
// 添加存储
sh->vAddShape(sh,s1);
// 正方形类2
square*s2 = (square*)square_new();
s2->baseShape.vInit(s2,"square 2",6);
// 添加存储
sh->vAddShape(sh,s2);
// 遍历打印
for(int i=0;i<sh->shapeCount;++i)
{
printf("name:%s area:%.3f \n",sh->list[i]->vGetMyName(sh->list[i]),\
sh->list[i]->vGetMyarea(sh->list[i]));
}
// 由名字查找值
printf("find1:%.2f\n",sh->vGetValueByname(sh,"123"));
printf("find2:%.2f\n",sh->vGetValueByname(sh,"square 2"));
return 0;
}
类的定义:
// 接口
INTERFACE (baseShape)
{
char name[10];
float value;
void (*vInit) (void*,char*,float);
float (*vGetMyarea) (void*);
char* (*vGetMyName) (void*);
float (*vGetMyValue) (void*);
};
// 圆类
CLASS (circle)
{
IMPLEMENTS (baseShape);
};
// 正方形类
CLASS (square)
{
IMPLEMENTS (baseShape);
};
// 形状类
CLASS (shape)
{
int shapeCount;
int shapeSize;
void (*vInit) (void*,int);
float (*vGetValueByname) (void*,char*);
int (*vAddShape) (void*,void*);
baseShape**list;
};
类的实现:
/******** 圆类 ***********/
// 初始化
static void cInit(void*p,char*name,float value)
{
circle*pthis = (circle*)p;
strcpy(pthis->baseShape.name,name);
pthis->baseShape.value = value;
}
// 获取名字
static char* cgetMyName(void*p)
{
circle*pthis = (circle*)p;
return pthis->baseShape.name;
}
// 获取名字
static float cgetMyValue(void*p)
{
circle*pthis = (circle*)p;
return pthis->baseShape.value;
}
// 计算面积
static float cGetArea(void*p)
{
circle*pthis = (circle*)p;
return 3.14*pthis->baseShape.value*pthis->baseShape.value;
}
// 使用构造器构造类
CTOR (circle)
FUNCTION_SETTING(baseShape.vInit,cInit);
FUNCTION_SETTING(baseShape.vGetMyarea,cGetArea);
FUNCTION_SETTING(baseShape.vGetMyName,cgetMyName);
FUNCTION_SETTING(baseShape.vGetMyValue,cgetMyValue);
END_CTOR
/************ 正方形类 *****************/
// 初始化
static void sInit(void*p,char*name,float value)
{
square*pthis = (square*)p;
strcpy(pthis->baseShape.name,name);
pthis->baseShape.value = value;
}
// 获取名字
static char* sgetMyName(void*p)
{
square*pthis = (square*)p;
return pthis->baseShape.name;
}
// 获取名字
static float sgetMyValue(void*p)
{
square*pthis = (square*)p;
return pthis->baseShape.value;
}
// 计算面积
static float sGetArea(void*p)
{
square*pthis = (square*)p;
return pthis->baseShape.value*pthis->baseShape.value;
}
// 使用构造器构造类
CTOR (square)
FUNCTION_SETTING(baseShape.vInit,sInit);
FUNCTION_SETTING(baseShape.vGetMyarea,sGetArea);
FUNCTION_SETTING(baseShape.vGetMyName,sgetMyName);
FUNCTION_SETTING(baseShape.vGetMyValue,sgetMyValue);
END_CTOR
/********* 接口类 ******/
//初始化形状类
static void initShape(void*p,int size)
{
shape*pthis = (shape*)p;
pthis->shapeCount = 0;
pthis->shapeSize = size;
pthis->list = (baseShape**)malloc(sizeof(baseShape*)*pthis->shapeSize);
}
// 向形状类添加一个形状
static int addShape(void*p,void*newP)
{
shape*pthis = (shape*)p;
if(pthis->shapeCount+1 > pthis->shapeSize)
return -1;
baseShape*newp = (baseShape*)newP;
pthis->list[pthis->shapeCount++] = newp;
return 0;
}
//获取形状的边长或者半径
static float getValueByname(void*p,char*name)
{
shape*pthis = (shape*)p;
for(int i=0;i<pthis->shapeCount;++i)
{
if(strcmp(name,pthis->list[i]->vGetMyName(pthis->list[i])) == 0)
return pthis->list[i]->vGetMyValue(pthis->list[i]);
}
return -1;
}
// 使用构造器构造类
CTOR (shape)
FUNCTION_SETTING(vInit,initShape);
FUNCTION_SETTING(vAddShape,addShape);
FUNCTION_SETTING(vGetValueByname,getValueByname);
END_CTOR
示例代码的储存示例:
运行结果:
相关文章
博主也整理了一些其他文章,欢迎大家翻阅!!!🤤🤤🤤