【UML+OOPC嵌入式C语言开发】C语言使用OOPC的接口机制实现多态

知识讲解

介绍多态

  多态是指对于同一个消息,不同的类对象会做出不同的反应。
  在面向对象语言中(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

示例代码的储存示例:
在这里插入图片描述

运行结果:
在这里插入图片描述

相关文章

  博主也整理了一些其他文章,欢迎大家翻阅!!!🤤🤤🤤

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值