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>
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
};
void initA(A
*p
, int a
, int b
)
{
p
->vptr
= &A_Vtable
;
p
->a
= a
;
p
->b
= b
;
}
typedef struct B
{
A a
;
int b
;
void dong11();
void dong66();
void initB(B
* p
, int a
, int b
);
}B
;
void dong11()
{
printf("派生类 dong11\n");
}
void dong66()
{
printf("派生类 dong66\n");
}
typedef struct
{
Vtable vtable
;
void(*p
)();
}Vtable2
;
Vtable2 B_vtable
= { { &dong11
, &dong2
}, &dong66
};
void initB(B
* p
,int a
, int b
)
{
p
->a
.vptr
= &B_vtable
;
p
->b
= b
;
}
void test1()
{
A aa
;
initA(&aa
, 10, 20);
((Vtable
*)aa
.vptr
)->v1();
((Vtable
*)aa
.vptr
)->v2();
}
void test2()
{
B
*b
= (B
*)malloc(sizeof(B
));
initB(b
, 10, 20);
A
*a
= (A
*)b
;
((Vtable2
*)(a
->vptr
))->p();
printf("\n------见证奇迹的时候到了,实现多态------\n\n");
((Vtable
*)(a
->vptr
))->v1();
((Vtable
*)(a
->vptr
))->v2();
}
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
};
typedef struct
{
Vtable vtable
;
void(*p
)();
}Vtable2
;
Vtable2 B_vtable
= { { &dong11
, &dong2
}, &dong66
};
所以,至始至终我们利用的就是Vtable2指向的函数。可以调用v1那是因为Vtable2中有Vtable,而Vtable中有v1
*/