代码改变世界

对OO中封装的理解

2010-04-18 18:46  2323  阅读(504)  评论(0编辑  收藏  举报

 

1. 对封装的疑问

 

也不知道是谁第一次把封装定义为面向对象的三大特性之一。在面向对象之前,主要的软件开发过程是面向过程。如果说封装是面向对象的三大特性之一,那么面向过程是不是不能实现封装呢?那么要先看看面向对象中的封装的具体含义是什么。

 

2. 国内对封装的定义

 

我们来先看网上一般对封装的定义:

封装:也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

这个定义提到抽象一词:抽象是达到封装的目的的方法。

但是看了维基百科的定义和解释,感觉这个定义存在一定的问题,或者说是没有全面的,有重点地说明封装在面向对象的作用。

 

3. Wikipekia对封装的描述

 

下面是维基百科的翻译:

这些内容来自wikipekia的英文翻译,中文版wikipekia对封装的定义有些苍白,所以没有采用。

在面向对象语言中,封装是指下面两个相关但有区别的概念之一,但有时又同时具备这两个概念的含义。

a.一种限制访问对象组件的语言机制

b.一种实现方法和数据绑定的语言结构(construct)

编程语言研究人员和学术机构有的仅仅采用第一点作为面向对象语言特性,有的和第二点一起作为面向对象的特性。

第二个定义的现实根据是:很多的OO语言对信息隐藏机制没有提供内建的支持,或者该机制可以被override。因此对于那些喜欢第二个定义的人来说,信息隐藏被作为一个单独的特性。

 

3.1. 信息隐藏机制

 

封装是指一个对象的内部数据对外部对象来说是隐藏的。通常地,对象自己的方法才可以直接操作自己的field.这个规则对一些语言是强制性的,比如Smalltalk,但是其他大多数OO语言(C++,Java)则可以让程序员决定那些可以隐藏,通常的做法是采用关键字public 和private来达到目的. 极少数的OO语言,比如Python,并没有提供隐藏field的机制。

隐藏对象的内部细节可以防止程序员把对象的内部数据设置成一个不合理的状态,从而可以保护对象数据的完整性。封装的另外一个好处就是:通过限制组件之间的依赖来减少系统的复杂度,提高健壮性。

信息隐藏机制并非是OO语言独有的。抽象数据类的实现,例如modules提供了一种类似封装的形式。这种相似性的来源是:实际上这两个概念都依赖于既存类型背后的数学原理 (这句好难懂,Scalas提供了既存类型).

 

3.2. 一种绑定机制

 

[没有解释]

 

3.3. 参考文献(这里没有列出所有的)

Michael Lee Scott, Programming language pragmatics, Edition 2, Morgan Kaufmann, 2006, ISBN 0126339511, p. 481: "Encapsulation mechanisms enable the programmer to group data and the subroutines that operate on them together in one place, and to hide irrelevant details from the users of an abstraction."

 

4. 回溯到面向过程

 

面向过程能不能实现封装,以C为例(本人对C仅仅有一点点基础),应该说,C没有对封装提供内建的支持,但是可以在一定程度上实现封装。参见这篇文章:

C语言封装数据与方法

 

5. 结论

 

封装包含两个含义:

a. 信息隐藏

b. 方法和数据的绑定操作

 

C#和VB.NET对封装的支持

信息隐藏方面有关键字:public,private,protected, Friend(VB.NET),internal(C#).

方法和数据的绑定操作:这个所有OOPL都提供了内建的支持。