介绍多态
多态是指对于同一个消息,不同的类对象会做出不同的反应。
在面向对象语言中(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);// 圆类1circle*c1 = (circle*)circle_new();c1->baseShape.vInit(c1,"circle 1",2);// 添加存储sh->vAddShape(sh,c1);// 圆类2circle*c2 = (circle*)circle_new();c2->baseShape.vInit(c2,"circle 2",3);// 添加存储sh->vAddShape(sh,c2);// 正方形类1square*s1 = (square*)square_new();s1->baseShape.vInit(s1,"square 1",4);// 添加存储sh->vAddShape(sh,s1);// 正方形类2square*s2 = (square*)square_new();s2->baseShape.vInit(s2,"square 2",6);// 添加存储sh->vAddShape(sh,s2);// 遍历打印for(int i=0;ishapeCount;++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;ishapeCount;++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
示例代码的储存示例:
运行结果:
博主也整理了一些其他文章,欢迎大家翻阅!!!🤤🤤🤤
上一篇:VScode 插件【配置】