俺使用的C语言面向对象范式(第二节:构造Composition 与 第三节:继承Inheritance)
2011-05-12 16:59
489 查看
二、使用构造Composition代替继承Inheritance
如果现在有两个接口Iface1, Iface2. 每个接口对应一个数据类型(结构体)。
如果有一个类ClassAnother需要实现接口Iface1和Iface2:
为ClassAnother创建接口Iface1和Iface2的实例:
为ClassAnother写一个初始化函数:
实例化ClassAnother的一个对象:
调用个函数试试:)
再试试face2的:
小结:
代码继续清爽。使用Composition还是清晰一点呀,要是以继承为主,就要带上很多ctor,dtor,甚至父类指针这些俺觉得都属于"c语言偏僻技巧"。俺想要是维护代码的人看了父类指针不断往上指,估计还真是要砍人了。
三、 不愿意出现的继承Composition
在很多C面向对象的文章中都提到了如何去实现继承。用struct去封装类成员吧,继承一次套一层?用宏去封装吧,最后宏套宏的?俺认为这些都属于"C语言偏僻技巧",这是另外一个不建议在C语言里主推继承的原因。
但是有些类的确又避免不了继承的出现,那就只好老老实实的一个成员一个成员写上去了。
定义基类:
定义子类:
父类构造函数:
子类构造函数:
实例化ClassDerived:
调用个函数试试:) ~~
小结:
其实上边继承的办法还算清晰。再加多几层也没有关系,但是在代码层来看就很难看出继承的关系了,因为没有用struct也没有用宏进行封装。尽量避免吧。
参考:
1.博客文章:《我所偏爱的 C 语言面向对象编程范式》 云风的BLOG
2.程序代码:《LW_OOPC》 http://sourceforge.net/projects/lwoopc/
3.图书:《Object-oriented Programming with ANSI-C》
4.图书:《Python源码剖析》
如果现在有两个接口Iface1, Iface2. 每个接口对应一个数据类型(结构体)。
struct Dface1; struct Dface2; struct Iface1{ void(*init)(struct Dface1* data); void(*dosomething)(struct Dface1* data); }; struct Iface2{ void(*init)(struct Dface2* data); void(*dosomething)(struct Dface2* data); };
如果有一个类ClassAnother需要实现接口Iface1和Iface2:
struct ClassAnother{ struct Iface1* i_face1; struct Iface2* i_face2; struct Dface1 d_face1; // 这里不使用指针 struct Dface2 d_face2; // 这里不使用指针 };
为ClassAnother创建接口Iface1和Iface2的实例:
struct Iface1 i_face1_for_ClassAnother = { face1_init_for_ClassAnother, face1_dosomething_for_ClassAnother, }; struct Iface2 i_face2_for_ClassAnother = { face2_init_for_ClassAnother, face2_dosomething_for_ClassAnother, };
为ClassAnother写一个初始化函数:
ClassAnother_init(struct ClassAnother* c) { c->i_face1 = &i_face1_for_ClassAnother; //注意呀!要先初始化接口指针! c->i_face2 = &i_face2_for_ClassAnother; //第二个接口指针 c->i_face1->init(&c->d_face1); c->i_face2->init(&c->d_face2); }
实例化ClassAnother的一个对象:
struct ClassAnother ObjectAnother; ClassAnother_init(&ObjectAnother);
调用个函数试试:)
ObjectAnother->i_face1->dosomething(&ObjectAnother.d_face1);
再试试face2的:
ObjectAnother->i_face2->dosomething(&ObjectAnother.d_face2);
小结:
代码继续清爽。使用Composition还是清晰一点呀,要是以继承为主,就要带上很多ctor,dtor,甚至父类指针这些俺觉得都属于"c语言偏僻技巧"。俺想要是维护代码的人看了父类指针不断往上指,估计还真是要砍人了。
三、 不愿意出现的继承Composition
在很多C面向对象的文章中都提到了如何去实现继承。用struct去封装类成员吧,继承一次套一层?用宏去封装吧,最后宏套宏的?俺认为这些都属于"C语言偏僻技巧",这是另外一个不建议在C语言里主推继承的原因。
但是有些类的确又避免不了继承的出现,那就只好老老实实的一个成员一个成员写上去了。
struct Dface; struct Iface{ void(*init)(struct Dface* data); void(*dosomething)(struct Dface* data); }; struct Imore{ void(*init)(struct Dmore* data); void(*domore)(struct Dmore* data); };
定义基类:
struct ClassBase{ struct Iface* i_face; struct Dface d_face; };
定义子类:
struct ClassDerived{ struct Iface* i_face; struct Imore* i_more; struct Dface d_face; struct Dmore d_more; int w,h,y; };
父类构造函数:
void ClassBase_init(struct ClassBase* o) { o->i_face = &i_face_for_ClassBase; o->i_face->init(&o->d_face); }
子类构造函数:
void ClassDerived_init(struct ClassDerived* o) { ClassBase_init((struct ClassBase*)o); o->i_more = &i_more_for_ClassDerived; o->i_more->init(&o->d_more); }
实例化ClassDerived:
struct ClassDerived Object; ClassDerived_init(&Object);
调用个函数试试:) ~~
Object.i_face->dosomething((struct Dface*)&Object.d_face);
小结:
其实上边继承的办法还算清晰。再加多几层也没有关系,但是在代码层来看就很难看出继承的关系了,因为没有用struct也没有用宏进行封装。尽量避免吧。
参考:
1.博客文章:《我所偏爱的 C 语言面向对象编程范式》 云风的BLOG
2.程序代码:《LW_OOPC》 http://sourceforge.net/projects/lwoopc/
3.图书:《Object-oriented Programming with ANSI-C》
4.图书:《Python源码剖析》
相关文章推荐
- [阅读笔记]面向对象的设计法则--法则1:优先使用(对象)组合,而非(类)继承 Favor Composition Over Inheritance
- 08_面向对象【帮助文档的制作和作用、如何使用JDK提供的帮助文档、代码块概述(局部代码块,构造代码块,静态代码块)和讲解、继承】
- 俺使用的C语言面向对象范式(前言与第一节:一个简单类的封装)
- 源码-使用组合替代继承实现新类(Using Composition Rather Than Inheritance)
- Java学习之面向对象(方法的重写 overwrite,super的使用,继承中的构造方法)
- 结合使用组合(composition)和继承(inheritance)
- 继承(Inheritance)与复合(Composition)关系下的构造与析构
- React-----Composition(构造)VS Inheritance(继承)
- 俺使用的C语言面向对象范式(第四节:多态的实现 与 总结)
- c语言面向对象:线程的派生类使用实例
- 黑马程序员_Java基础_面向对象,封装,继承,单例设计模式,构造函数,构造代码块
- C语言也可以“面向对象”—— C语言实现封装、继承和多态
- 使用C语言进行面向对象的开发--GObject入门[1]
- 使用C语言进行面向对象的开发--GObject入门[3]
- 谨慎使用 multiple inheritance(多继承)
- c++面向对象之复合(composition)、委托(delegation)、继承(inheritance)--(boolan)
- 构造方法在继承中的使用
- java笔记之面向对象,构造,继承
- [struts2学习笔记] 第二节 使用Maven搞定管理和构造Struts 2 Web应用程序的七个步骤
- 面向对象的设计法则(1)——优先使用(对象)组合,而非(类)继承(转)