您的位置:首页 > 编程语言 > C语言/C++

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用于返回该形状的周长。所子继承“形状”的子类都必须实现这两个接口。

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);}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: