模块化C代码与UML对象模型之间的映射(2)——抽象类与继承

 今天继续写模块化C代码与UML类图的转换,所举例子也许粗糙,主要是演示一下思路,时间允许的话我会尽量按正式的产品开发质量要求来完善代码示例。

1.4 抽象类与继承

抽象类是指继承关系树中位于树枝节点的用于被继承的类,如图1.5所示。抽象类具有以下特点:

(1)不能被实例化,所以没有Create或GetInstance方法;

(2)抽象类中方法可以没有实现体,称为抽象方法,它必须被子类重写。

(3)如果类中包含抽象方法,则必须定义为抽象类。

顺便说一下,图中void *privateData是类的私有字段,可以利用这个字段扩展功能或简单忽略之。后面有机会再举例说明。

 另外,I_DEV是类DEV实现的一组操作集合,公开给用户,这就是接口,下一节再详细举例说明。

UML示例:

图1.5 抽象类

  

C代码示例:

 

  1. ///   
  2.   
  3. //inheritance_utils.h   
  4.   
  5. #undef CONTAINING_RECORD   
  6. #define CONTAINING_RECORD(address, type, field) \   
  7.      ((type *)( (char *)(address) - (unsigned long)(&((type*)0)->field)))  
  8.   
  9. ///   
  10. //DEV.h   
  11. /* 定义设备操作接口*/  
  12. struct I_DEV{  
  13.      int (*Add)(struct DEV *, int somePara);  
  14.      int (*Delete)(struct DEV *, int somePara);  
  15.      int (*Query)(struct DEV *, int somePara);  
  16.      int (*Reset)(struct DEV *, int somePara);  
  17. };  
  18.   
  19. /* 定义设备类*/  
  20. struct DEV{  
  21.      void (*Destroy)(struct DEV *);  
  22.      void (*Method1)(struct DEV *);  
  23.      void (*Method2)(struct DEV *);  
  24.      const struct I_DEV *itf;  /* 接口*/  
  25.      void *privateData;  
  26. };  
  27.   
  28. //抽象类不能实例化,没有Create   
  29. void DEV_Init(struct DEV *DEV, const struct I_DEV *itf); //注意init方法职责是初始化而非实例化   
  30. void DEV_Destroy(struct DEV *self);  
  31. void DEV_Method1(struct DEV *self);//Method1是具体方法,DEV.c中实现Method1   
  32. //Method2是抽象方法,DEV.c中没有Method2实现体   
  33.    
  34. ///   
  35. //DEV.c   
  36.   
  37. #include "DEV.h"   
  38. void DEV_Init(struct DEV *DEV, const struct I_DEV *itf)  
  39. {  
  40.      assert(DEV != NULL);  
  41.      memset(DEV, 0, sizeof *DEV);  
  42.      DEV->itf = itf;  
  43.      DEV->Method1 = DEV_Method1;  
  44. }  
  45.   
  46. void DEV_Destroy(struct DEV *self)  
  47. {  
  48.      if (self != NULL)  
  49.      {  
  50.          free(self);  
  51.      }  
  52. }  
  53.   
  54. void DEV_Method1(struct DEV *self)  
  55. {  
  56.      printf("hello, I'm concrete method!\r\n");  
  57. }  
  58.   
  59.   
  60. ///   
  61. //WASHER_DEV.h   
  62. struct WASHER;  /* 隐藏具体类的细节*/  
  63.   
  64. struct WASHER *WASHER_Create(int type, int id, char *name);  
  65. //…   
  66.   
  67. ///   
  68. //WASHER.c   
  69.   
  70. #include "DEV.h"   
  71. #include “WASHER_DEV.h”   
  72.    
  73. /* 定义WASHER设备类*/  
  74. struct WASHER  
  75. {  
  76.      int type;  
  77.      int id;  
  78.      char *name;  
  79.      struct DEV DEV; //继承DEV类   
  80.      void *moreData;  
  81. };  
  82.    
  83. /* 实现I_DEV接口*/  
  84. static int WASHER_Add(struct DEV *DEV, int somePara)  
  85. {  
  86.      struct WASHER *WASHER;  
  87.      WASHER = CONTAINING_RECORD(DEV, struct WASHER, DEV);  
  88.      DEV->privateData = WASHER;  
  89.      printf("[WASHER_Add]type = %d, id = %d, name = %s\r\n", WASHER->type, WASHER->id, WASHER->name);  
  90.      return 0;  
  91. }  
  92.    
  93. static int WASHER_Query(struct DEV *DEV, int somePara)  
  94. {  
  95.      struct WASHER *WASHER = (struct WASHER *)DEV->privateData;  
  96.      printf("[WASHER_Query]type = %d, id = %d, name = %s\r\n", WASHER->type, WASHER->id, WASHER->name);  
  97.      return 0;  
  98. }  
  99.    
  100. struct I_DEV WASHERItf = {  
  101.      WASHER_Add,  
  102.      NULL,  
  103.      WASHER_Query,  
  104.      NULL,  
  105. };  
  106.   
  107. /* 派生类实现基类的抽象方法*/  
  108. static void WASHER_DEV_Method2(struct DEV *self)  
  109. {  
  110.      printf("hello, I'm abstract method, implemented by WASHER.\r\n");  
  111. }  
  112.    
  113. static void WASHER_setup_DEV(struct WASHER *WASHER)  
  114. {  
  115.      DEV_Init(&WASHER->DEV, &WASHERItf);  
  116.      WASHER->DEV.Method2 = WASHER_DEV_Method2;  
  117. }  
  118.    
  119. static void WASHER_init(struct WASHER *self, int type, int id, char *name)  
  120. {  
  121.      memset(self, 0, sizeof(struct WASHER));  
  122.      self->type = type;  
  123.      self->id;  
  124.      self->name = name;  
  125.      WASHER_setup_DEV(self);  
  126. }  
  127.   
  128. struct WASHER *WASHER_Create(int type, int id, char *name)  
  129. {  
  130.      struct WASHER *WASHER = (struct WASHER *)malloc(sizeof(struct WASHER));  
  131.      WASHER_init(WASHER, type, id, name);  
  132.      return WASHER;  
  133. }  
  134. ///   
  135. //test_WASHER_DEV.c   
  136.   
  137. #include "WASHER_DEV.h"   
  138.   
  139. TEST(test_DEV_inheritance, test_demo)  
  140. {  
  141.      int type = 3;  
  142.      int id = 1;  
  143.      char *name = "WASHER";  
  144.      struct WASHER * WASHER = WASHER_Create(type, id, name);  
  145.      // Usually register WASHER first. Here’s just a demo…   
  146.      //针对接口/抽象编程   
  147.      struct DEV *DEV = &(WASHER->DEV);  
  148.      EXPECT_EQ(0, DEV->itf->Add(DEV, 0xff));  
  149.      EXPECT_EQ(0, DEV->itf->Query(DEV, 0xff));  
  150.      DEV->Method1(DEV);  
  151.      DEV->Method2(DEV);  
  152. }  
  153.   
  154. //e.g. user: bd = add(type, id, "DEVname");  query(bd, para);   
  155. 又到11点了,该睡觉觉罗~~  


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值