C语言中的面向对象思想
2016-07-21 16:46
281 查看
C语言的对象化模型
面向对象的特征主要包括:
.封装,隐藏内部实现
.继承,复用现有代码
.多态,改写对象行为
封装
封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装使数据和加工该数据的方法(函数)封装为一个整体,以实现独立性很强的模块,使得用户只能见到对象的外特性(对象能接受哪些消息,具有那些处理能力),而对象的内特性(保存内部状态的私有数据和实现加工能力的算法)对用户是隐蔽的。封装的目的在于把对象的设计者和对象者的使用分开,使用者不必知晓行为实现的细节,只须用设计者提供的消息来访问该对象。
在C语言中,大多数函数的命名方式是动词+名词的形式,例如要获取一个string,会命名
成get_string,重点在get这个动作上。面向对象编程中刚好相反,命名为str_get,即名词+动词的形式,重点在名词上,体现了一个对象的方法。
另外对于某些方法,仅局限在对象内部使用,它们将采用static修辞把作用范围局限在一个文件的内部。通过这样的方式,把一些不想让用户知道的信息屏蔽在封装里,用户只看到了外层的接口,从而形成了面向对象中的最基本的对象封装实现。
所谓封装,通俗地说,就是一个姑娘化了妆,只给你看她想让你看的那一面,至于里面是什么样,不给你看。说到封装就得说隐藏,这是对兄弟概念;其实我理解隐藏是更深的封装,完全不给你看见,而封装可能是犹抱琵琶半遮面。封装在 C++ 语言中有 protected 、 private 关键字在语言层面上支持,而 C 语言中没有这些。 C 有结构体( struct ),其实可以实现封装和隐藏。
继承
继承性是子类自动共享父类之间数据和方法的机制。它由类的派生功能体现。一个类直接继承其它类的全部描述,同时可修改和扩充。继承具有传递性。继承分为单继承(一个子类只有一父类)和多重继承(一个类有多个父类,当前RT-Thread的对象系统不能支持)。类的对象是各自封闭的,如果没继承性机制,则类对象中数据、方法就会出现大量重复。继承不仅支持系统的可重用性,而且还促进系统的可扩充性。
在 C 语言中可以用结构体的包含来实现继承关系。 继承在语法层面上看,有数据成员、函数,数据成员通过上面的方法自动就“继承”了,至于函数,在结构体表示为函数指针,其实也是一个数据成员,是个指针而已,也会自动“继承”。之所以还要在这里列出来说明,是因为 C++ 中有一个很重要的概念:重载。要在 C 中完整实现有点儿麻烦。
其实,你知道C语言很强大,但是你可能不知道它强大到能够实现面向对象编程的。
C语言没有class这样的关键字,只有struct。但是struct只能保存数据成员,不能保存方法。可是,C语言的精髓就在于指针,在struct中加入相应方法的函数指针就可以完全实现了类的功能了。只要在创建实例,初始化时把相应的函数指针赋值就行了。
有了类还不能实现面向对象.我们还需要继承呀.那么怎样继承呢?也很简单,直接把父类作为子类的第一个数据元素就搞掂了。
继承搞掂了,还是不行的。我们还需要封装好每一个类,实现封装的方法就是使用static和extern这两个关键字就行了。
就这样,我们就用C语言实现了面向对象的编程了.
c语言是一种结构化编程语言,以模块工能和处理过程设计为主,实现数据与代码分隔化。面向对象方法论中,核心是类,类是用于创造对象的模板,其三要素为:封装,继承,多态。C语言本身对面向对象的支持很弱,但可以通过一些技巧来实现。下面通过一个具体的实例来说明实现这此技巧。
实例:
在几何中,所有的几何类型都继承父类“形状(shape)”,父类“形状”有两处属性s_type和s_name。其中s_type用于表示该形状所属的类型,s_name用于表于该形状态的名称。而且父类shape还有两个虚接口,一个为shape_area用于返回该形状的面积,一个为shape_perimeter用于返回该形状的周长。所子继承“形状”的子类都必须实现这两个接口。
几何体“三角形(triangle)”继承父类“形状”,并且实现了父类的两个虚接口。“三角形”有三条边,分别用t_side_a,t_side_b,t_side_c来表于三条边的长度。
测试代码:
运行结果:
struct shape;struct shape_ops{ float (*so_area)(struct shape*); int (*so_perimeter)(struct shape*);};struct shape{
int* s_type; char* s_name; struct shape_ops* s_ops; };float shape_area(struct shape* s) { return s->s_ops->so_area(s); }int shape_perimeter(struct shape* s){ return s->s_ops->so_perimeter(s);}
面向对象的特征主要包括:
.封装,隐藏内部实现
.继承,复用现有代码
.多态,改写对象行为
封装
封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装使数据和加工该数据的方法(函数)封装为一个整体,以实现独立性很强的模块,使得用户只能见到对象的外特性(对象能接受哪些消息,具有那些处理能力),而对象的内特性(保存内部状态的私有数据和实现加工能力的算法)对用户是隐蔽的。封装的目的在于把对象的设计者和对象者的使用分开,使用者不必知晓行为实现的细节,只须用设计者提供的消息来访问该对象。
在C语言中,大多数函数的命名方式是动词+名词的形式,例如要获取一个string,会命名
成get_string,重点在get这个动作上。面向对象编程中刚好相反,命名为str_get,即名词+动词的形式,重点在名词上,体现了一个对象的方法。
另外对于某些方法,仅局限在对象内部使用,它们将采用static修辞把作用范围局限在一个文件的内部。通过这样的方式,把一些不想让用户知道的信息屏蔽在封装里,用户只看到了外层的接口,从而形成了面向对象中的最基本的对象封装实现。
所谓封装,通俗地说,就是一个姑娘化了妆,只给你看她想让你看的那一面,至于里面是什么样,不给你看。说到封装就得说隐藏,这是对兄弟概念;其实我理解隐藏是更深的封装,完全不给你看见,而封装可能是犹抱琵琶半遮面。封装在 C++ 语言中有 protected 、 private 关键字在语言层面上支持,而 C 语言中没有这些。 C 有结构体( struct ),其实可以实现封装和隐藏。
继承
继承性是子类自动共享父类之间数据和方法的机制。它由类的派生功能体现。一个类直接继承其它类的全部描述,同时可修改和扩充。继承具有传递性。继承分为单继承(一个子类只有一父类)和多重继承(一个类有多个父类,当前RT-Thread的对象系统不能支持)。类的对象是各自封闭的,如果没继承性机制,则类对象中数据、方法就会出现大量重复。继承不仅支持系统的可重用性,而且还促进系统的可扩充性。
在 C 语言中可以用结构体的包含来实现继承关系。 继承在语法层面上看,有数据成员、函数,数据成员通过上面的方法自动就“继承”了,至于函数,在结构体表示为函数指针,其实也是一个数据成员,是个指针而已,也会自动“继承”。之所以还要在这里列出来说明,是因为 C++ 中有一个很重要的概念:重载。要在 C 中完整实现有点儿麻烦。
其实,你知道C语言很强大,但是你可能不知道它强大到能够实现面向对象编程的。
C语言没有class这样的关键字,只有struct。但是struct只能保存数据成员,不能保存方法。可是,C语言的精髓就在于指针,在struct中加入相应方法的函数指针就可以完全实现了类的功能了。只要在创建实例,初始化时把相应的函数指针赋值就行了。
有了类还不能实现面向对象.我们还需要继承呀.那么怎样继承呢?也很简单,直接把父类作为子类的第一个数据元素就搞掂了。
继承搞掂了,还是不行的。我们还需要封装好每一个类,实现封装的方法就是使用static和extern这两个关键字就行了。
就这样,我们就用C语言实现了面向对象的编程了.
c语言是一种结构化编程语言,以模块工能和处理过程设计为主,实现数据与代码分隔化。面向对象方法论中,核心是类,类是用于创造对象的模板,其三要素为:封装,继承,多态。C语言本身对面向对象的支持很弱,但可以通过一些技巧来实现。下面通过一个具体的实例来说明实现这此技巧。
实例:
在几何中,所有的几何类型都继承父类“形状(shape)”,父类“形状”有两处属性s_type和s_name。其中s_type用于表示该形状所属的类型,s_name用于表于该形状态的名称。而且父类shape还有两个虚接口,一个为shape_area用于返回该形状的面积,一个为shape_perimeter用于返回该形状的周长。所子继承“形状”的子类都必须实现这两个接口。
struct shape; struct shape_ops { float (*so_area)(struct shape*); int (*so_perimeter)(struct shape*); }; struct shape { int* s_type; char* s_name; struct shape_ops* s_ops; }; float shape_area(struct shape* s) { return s->s_ops->so_area(s); } int shape_perimeter(struct shape* s) { return s->s_ops->so_perimeter(s); }
几何体“三角形(triangle)”继承父类“形状”,并且实现了父类的两个虚接口。“三角形”有三条边,分别用t_side_a,t_side_b,t_side_c来表于三条边的长度。
struct rectangle { struct shape r_base; int r_width; int r_height; }; float rectangle_area(struct shape* s) { struct rectangle* r=(struct rectangle*)s; return r->r_width*r->r_height; } int rectangle_perimeter(struct shape* s) { struct rectangle* r=(struct rectangle*)s; return (r->r_width+r->r_height)*2; } struct shape_ops rectangle_ops= { rectangle_area, rectangle_perimeter, }; struct rectangle* rectangle_create(int width, int height) { struct rectangle* ret=(struct rectangle*)malloc(sizeof(*ret)); ret->r_base.s_name="rectangle"; ret->r_base.s_ops=&rectangle_ops; ret->r_height=height; ret->r_width=width; return ret; }
测试代码:
int main() { struct shape* s[4]; s[0]=triangle_create(5,5,4); s[1]=triangle_create(3,4,5); s[2]=rectangle_create(10,12); s[3]=rectangle_create(5,8); int i=0; for(i=0;i<</span>4;i++) { float area=shape_area(s[i]); int perimeter=shape_perimeter(s[i]); char* name=s[i]->s_name; printf("name:%s ,area:%.2f ,perimeter:%d\n",name,area,perimeter); } return 0; }
运行结果:
name:triangle ,area:9.17 ,perimeter:14 name:triangle ,area:6.00 ,perimeter:12 name:rectangle ,area:120.00 ,perimeter:44 name:rectangle ,area:40.00 ,perimeter:26
struct shape;struct shape_ops{ float (*so_area)(struct shape*); int (*so_perimeter)(struct shape*);};struct shape{
int* s_type; char* s_name; struct shape_ops* s_ops; };float shape_area(struct shape* s) { return s->s_ops->so_area(s); }int shape_perimeter(struct shape* s){ return s->s_ops->so_perimeter(s);}
相关文章推荐
- C语言开发环境搭建
- 精通C++资源管理-在资源管理类中小心coping行为
- 猜拳游戏
- UVA 10106-Product
- atoi函数实现
- C++ hdoj 2009
- cout 未定义
- c++学习笔记(九):C++日期和时间
- 解决 multiple definition of 问题
- C语言 函数小总结
- 解读 C 语言中的指针
- C++ exe 传参
- c++学习笔记(八):C++字符串
- C/C++的内存泄漏检测工具Valgrind memcheck的使用经历
- C++ STL容器迭代器失效
- C++语法——static关键字
- 1084. Broken Keyboard (20)
- C/C++中函数传参方式简述
- 创建一个简单的VC++ Socket程序
- 一.数组和指针的差别二.函数的好处以及使用函数的注意项。三.用c语言如何实现面向对象?c语言哪些点体现了面向对象。