C语言实现封装、继承、多态

文章目录

  • C语言实现封装、继承、多态
    • 一. 封装
    • 二.继承
    • 三. 多态

一. 封装

C语言中虽然没有类,但有struct和指针。我们可以在一个struct中存入数据和函数指针,以此来模拟类行为。

typedef struct _Parent
{int a;int b;void (*print)(struct _Parent *This);}Parent;
  • 封装性的意义在于,函数和数据是绑在一起的,数据和数据是绑在一起的。这样,我们就可以通过简单的一个结构指针访问到所有的数据,遍历所有的函数。封装性,这是类拥有的属性,当然也是数据结构体拥有的属性。

二.继承

  • 如果要完全地用C语言实现继承,可能有点难度。但如果只是简单的做一下,保证子类中含有父类中的所有成员。这还是不难的。
typedef struct _Child
{  Parent parent;  int c;
}Child;
  • 在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题。

三. 多态

  • 这个特性恐怕是面向对象思想里面最有用的了。
  • 要用C语言实现这个特性需要一点点技巧,但也不是不可能的。
#include <stdio.h>
#include <stdlib.h>//模拟一个类A
typedef struct A
{void *vptr;//虚函数指针//下面内容可以删掉,写上的目的:看着像一个类//成员变量int a;int b;void initA(A *p, int a, int b);//虚函数void dong1();void dong2();
}A;//实现虚函数
void dong1()
{printf("基类  dong1\n");
}
void dong2()
{printf("基类  dong2\n");
}//模拟虚表结构
typedef struct
{void(*v1)();void(*v2)();
}Vtable;//模拟一个类中的虚表
Vtable A_Vtable = { &dong1, &dong2 };//精华在这:★a类可以调用dong1  dong2 这两个函数★//模拟A类的构造函数
void initA(A *p, int a, int b)//第一个是this指针,在c++中也会默认传一个this指针
{p->vptr = &A_Vtable;p->a = a;p->b = b;
}/////模拟派生类 B
typedef struct B
{A a;//父类的内容//下面内容可以删掉,写上的目的:看着像一个类int b;void dong11();void dong66();void initB(B* p, int a, int b);
}B;
//模拟派生类的虚函数
void dong11()//模拟覆盖dong1这个函数
{printf("派生类  dong11\n");
}
void dong66()
{printf("派生类  dong66\n");
}
//模拟子类虚表,增加了一个函数dong66
typedef struct
{Vtable vtable;void(*p)();
}Vtable2;//子类的虚表
//注意这里大括号一个不能少
//★b类可以调用dong11、dong2、dong66 这三个函数★
Vtable2 B_vtable = { { &dong11, &dong2 }, &dong66 };//B类构造函数
//为什么要a参数呢?初始化基类
void initB(B* p,int a, int b)
{//************重点**************//创建B类,但是需要初始化A类。继承A类中的虚表指针//initA((A*)p, a, b);           //我们这里用B类自己的虚表,一个类一个虚表p->a.vptr = &B_vtable;      p->b = b;
}///
//以下内容全是模拟//测试一下A类
void test1()
{A aa;initA(&aa, 10, 20);((Vtable*)aa.vptr)->v1();((Vtable*)aa.vptr)->v2();
}//测试一下B类
void test2()
{//创建B类B *b = (B*)malloc(sizeof(B));initB(b, 10, 20);//转成A类A *a = (A*)b;//现在表面上是父类,而我们可以调用父类没有而子类有的方法((Vtable2*)(a->vptr))->p();printf("\n------见证奇迹的时候到了,实现多态------\n\n");((Vtable*)(a->vptr))->v1();//子类覆盖了父类对象,调用的就是子类对象((Vtable*)(a->vptr))->v2();//子类没有覆盖父类对象,调用的就是父类对象
}//test3用来解惑的。其实我们b类不靠A就能调用父类,子类方法,test2实现的多态就是为了模拟C++
void test3()
{B *b = (B*)malloc(sizeof(B));initB(b, 10, 20);//下面两个地址是一样的,这里得仔细考虑。我也是调试了好久才发现其中的奥秘printf("%d\n", b->a.vptr);printf("%d\n", ((A*)b)->vptr);((Vtable*)(b->a.vptr))->v1();   ((Vtable*)(b->a.vptr))->v2();((Vtable2*)(b->a.vptr))->p();
}int main()
{test1();printf("---------------------------------------------\n\n");test2();printf("---------------------------------------------\n\n");test3();return 0;
}/*
**************************上面看着费劲----光看下面就行了
typedef struct
{void(*v1)();void(*v2)();
}Vtable;Vtable A_Vtable = { &dong1, &dong2 };//如果不单独测试A 这句话就是废话typedef struct
{//Vtable2有一个Vtable,所以Vtable2可以转化为Vtable使用v1 v2。 Vtable vtable;//但是我们赋值的时候是Vtable2  所以真真调用的时候,还是从Vtable2中调用void(*p)();
}Vtable2;Vtable2 B_vtable = { { &dong11, &dong2 }, &dong66 };所以,至始至终我们利用的就是Vtable2指向的函数。可以调用v1那是因为Vtable2中有Vtable,而Vtable中有v1
*/

C语言实现封装、继承、多态相关推荐

  1. c语言编程 菲薄拉,C语言设计模式-封装-继承-多态

    快过年了,手头的工作慢慢也就少了,所以,研究技术的时间就多了很多时间,前些天在CSDN一博客看到有大牛在讨论C的设计模式,正好看到了,我也有兴趣转发,修改,研究一下. 记得读大学的时候,老师就告诉我们 ...

  2. C语言设计模式-封装-继承-多态

    快过年了,手头的工作慢慢也就少了,所以,研究技术的时间就多了很多时间,前些天在CSDN一博客看到有大牛在讨论C的设计模式,正好看到了,我也有兴趣转发,修改,研究一下. 记得读大学的时候,老师就告诉我们 ...

  3. Java继承_Hachi君浅聊Java三大特性之 封装 继承 多态

    Hello,大家好~我是你们的Hachi君,一个来自某学院的资深java小白.最近利用暑假的时间,修得满腔java语言学习心得.今天小宇宙终于要爆发了,决定在知乎上来一场根本停不下来的Hachi君个人 ...

  4. python 参数类型的多态_【Python】面向对象:类与对象\封装\继承\多态

    六.Python面向对象--类与对象\封装\继承\多态 1.什么是面向对象编程 1.1 程序设计的范式:程序可控,易于理解 1.2 抽象并建立对象模型 1.3 程序是不同对象相互调用的逻辑.每个对象在 ...

  5. 大数据笔记8—java基础篇4(面向对象-封装-继承-多态)

    面向对象 一.面向对象 1.面向过程 1.2.举例 1.3.总结 二.面向对象 1.简述 2.举例 3.思想特点 2.1.类的定义格式 2.1.1.简述 2.2.2.格式 2.3.3.示例 三.类的使 ...

  6. python多态的三种表现形式_python小结----面向对象的三大特征(封装,继承,多态)

    面向对象的三大特征: 封装,继承,多态 面向对象的编程思想核心:高类聚,低耦合–程序的设计模式范畴 封装 什么是封装: 在面向对象编程的思想中,对代码进行高度封装,封装又叫包装 封装就是指将数据或者函 ...

  7. python--编写程序:实现乐手弹奏乐器,乐手可以弹奏不同的乐器而发出不同的声音------使用类的封装继承多态的问题/使用面向对象的思想,设计自定义类,描述出租车和家用轿车的信息

    编写程序:实现乐手弹奏乐器,乐手可以弹奏不同的乐器而发出不同的声音 ------使用类的封装继承多态的问题 class Instrumnet():#乐器类def make_sound(self):pa ...

  8. 小白理解——封装继承多态

                                      一.封装 是什么:首先是抽象,把事物抽象成一个类,其次才是封装.对外表示为一个对象,隐藏对象的属性和动作实现的细节,仅对外公开接口. ...

  9. Day55-每日一道Java面试题-Java 面向对象编程三大特性: 封装 继承 多态

    Java 面向对象编程三大特性: 封装 继承 多态 封装 封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问.但是如果一个类没有 ...

  10. 面向对象 编程及面向对象三大属性:封装 继承 多态

    面向对象 面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面.应用结构.应用平台.分布式系统.网络管理结构. ...

最新文章

  1. python创建列向量_关于Numpy中的行向量和列向量详解
  2. 洛谷P1016 旅行家的预算 贪心
  3. 将中文日期转换成自己想要的格式如:2018年09月29日转换成2018-09-29
  4. bzoj 2653 middle (可持久化线段树)
  5. svn错误 is already locked 解决方案
  6. MySQL查看和修改表的存储引擎
  7. 流线动态图python_Node.js Stream(流)
  8. oracle 提示存在lob,Oracle数据库出现ORA-19566 LOB坏块的处理记录
  9. 如果把去掉数组里面重复的项
  10. 算法题 20 或与加
  11. java8(2)--- Stream API
  12. js日期格式化写法及获取当前日期年月日、上一月
  13. 如何把照片裁剪成证件照指定尺寸比例?
  14. 怎么学单片机,怎么入门
  15. matlab 不等式约束,MATLAB进行fmincon函数优化时非线性不等式约束总是报错
  16. 简单理解工作量单位:人月、人日、人时
  17. 《面试补习》--来聊聊削峰填谷!
  18. Python 创建商店营业额模拟数据并对其分析
  19. JAVA_协同过滤算法商品推荐
  20. 怎么退出自适应巡航_20款奔驰GLE350改ACC自适应巡航

热门文章

  1. php redis命令大全,redis中key相关命令详解
  2. 用Visual Studio Code Debug世界上最好的语言(Mac篇)
  3. 一张图读懂阿里巴巴一站式研发协同云——云效
  4. 常用批处理命令总结之Find和FindStr
  5. [转]深入理解G1垃圾收集器
  6. JS~重写alter与confirm,让它们变成fancybox风格
  7. HADOOP-Checkpoint原理
  8. ASP.NET 2.0+Atlas编写鼠标拖放程序(2)
  9. CodeForces - 1174D Ehab and the Expected XOR Problem(构造+思维+位运算)
  10. CodeForces - 1427C The Hard Work of Paparazzi(dp+剪枝)