心寄笔端 附庸风雅

甘草的技术博客

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
面向对象初步
面向对象初步 我们开始讲述和程序设计相关的面向对象理论,主要涉及到消息,封装,继承,多态等内容。

消息
其实我并不喜欢消息这个概念,因为当时我学习面向对象导论的时候,已经有过Windows编程的经验了,而面向对象的消息和Windows的消息机制并无关系。
因为面向对象强调对象的行为和对象之间的相互作用,而这种行为是以消息体现出来的。当某一个对象收到消息的时候,则对象对此做出反应。而实际体现到具体的语言上,则往往是以方法的调用来体现这一概念的。 
obj.function();

我们给对象obj发送某消息,就是用调用对象obj的方法来表明这一概念的。如果有Objective-C的基础,那么理解这个概念将更加容易。
【1】一般有C语言基础的人,更习惯于称方法为函数,这里我统一称其为方法,是因为我觉得方法更多地带有行为的意味,而函数(似乎)更多地强调了数学上多输入,单输出的数学函数的概念。

面向对象的几个重要概念
封装(Encapsulation),继承(Inheritance),多态(Polymorphism)是面向对象三个重要的特性。
除此以外,还有许多重要的概念,比如说数据的封装和隐藏,方法的重写,等等。在后面我们将一一进行讲解。

封装(encapsulation)
封装,就是将数据和数据的操作进行封装,这涵盖了数据的封装,数据的隐藏,对象的抽象和描述,封装方法对数据进行操作,等等。
数据的封装
我们依然以Point为例。如果说一个Point的实例就表示了在笛卡尔二维坐标系上的一个点。那么我们说,我们用Point对象刻画了坐标系上的点。而 一个Point对象封装了两个int数据,很显然,二维平面上点,用一个横坐标和一个纵坐标就能唯一确定了。所以我们的代码是这样的。
class Point
{     
    
int x;
    
int y;
}

类Point封装了两个整型的数据,x和y。 数据的封装,是刻画对象的最基本的一种方式,它反映了has-a的关系。 我们说,对象Point有一个x(横坐标),也有一个y(纵坐标)。Point对象,和x,y对象就构成了has-a的关系。 据此,我们也可以刻画Rect对象了。
class Rect {
    Point p1;    
//Top-left point;
    Point p2;    //Bottom-right point
}

于是,我们有了一个Rect类,它用两个顶点描述了这个矩形。

数据的隐藏(Data Hiding)
【2】通常,Data Hiding被翻译为信息隐藏,而不是数据隐藏。但是我习惯于使用数据隐藏这个词汇。
在讲述数据隐藏之前,我们要先讲述为什么要实现数据隐藏。如果,我们把Point限制为表达屏幕上一点的坐标,那么有如下的规则:
( x >= 0, y >= 0, x <= ScreenWidth, y <= ScreenHeight)
但是,如果数据没有被隐藏,那么下面的代码可能就是一种尴尬。 Point p; p.x = -15; p.y = -30; 显然,这是一个无效的点坐标。我们无法在这个点上进行操作。比如说取得该点的象素值。所以,我们决定不给程序员这样的自由,而把数据封装起来。
class Point {
    
private int x;
    
private int y;
}

Point p; 
p.x 
= 5;    //Error, Compile error.

好了,程序员不可以胡作非为了,但是程序员也访问不到它了。
对数据的操作封装
class Point{
    
private int x = 0;
    
private int y = 0;
    
public void setX(int x) {
        
if (x >= 0 && x <= ScreenWidth){                    
            
this.x = x;
        }     
    }
}
这里,我们给出了方法setX(),它实现了对隐藏的数据的操作,并判断了输入的合法性。那么这就完整地实现了对数据的封装和隐藏。

我们真正要隐藏什么?

例子显示,数据的封装和隐藏,在对数据的操作上,具有防火墙功效,然而这只是最简单的一个方面,究竟我们在隐藏什么呢?实际上数据的封装和隐藏实现了对对象操作复杂性的封装和隐藏。 就 像驾驶汽车一样,在汽车内有着数不清的零部件和子系统,它们都是对象(我是说,它们都可以被看作是对象),他们都很复杂,而驾驶员只要看仪表,操纵方向盘和离合器什么的,就可以去兜风了。而根本不用去直接操作发动机本身,或者是变速箱什么的。而且,甚至不知道发动机都做了哪些事情,这种复杂性被操纵方向盘等方法给隐藏掉了。

我们在适当的地方,对前面谈过的内容进行一下总结。

目前为止,我们讲到了数据封装,数据封装是非常容易理解的,就像我们常常看到的一些Java代码,每一个类里面都会有好几个private的成员,相应地,它们还有一些public的set和get方法,此外,还有许多的public方法,它们会去操作那些数据成员。这个就是我们所能看到最基本的封装了(当然了,这其中有很多并不明智的做法)。但是,这仅仅是一个开始,我们暂时还没有苛求一个方法更多的细节。

至少,我们现在,可以考虑的问题,就是给一个对象有【1】哪些成员,添加哪些方法。


【1】本来,我在这里用到“聚合”一词,但是现在只用“有”一个字。我们还是要好好考量“聚合”、“组合”这两个词语的。... ...<待>

一言以蔽之,聚合和组合,不要从代码形式上去判别,而是从语义上进行分析。

 


posted on 2008-06-06 12:19  甘草  阅读(552)  评论(0编辑  收藏  举报
Baidu
Google
心寄笔端
TEST
以后我会加上Power By的,先别介意