第 1 章 对象入门
“为什么面向对象的编程会在软件开发领域造成如此震憾的影响?”
对象抽象于现实,面向对象编程能够让人们更容易理解程序。
1 . 1 抽象的进步
一般程序设计需要考虑计算机的结构,而非考虑问题本身的结构。在机器模型(位于“机器空间”)与实际解决的问题模型(位于“问题空间”)之间,程序员必须建立起一种联系。这个过程要求人们付出较大的精力,而且由于它脱离了编程语言本身的范围,造成程序代码很难编写,而且要花较大的代价进行维护。
面向对象的程序设计将问题空间中的元素以及它们在方案空间的表示物称作“对象”(Object)。根据机器对象来解决问题对象,而不是根据机器空间。然而,仍有一个联系途径回到机器空间。
(1)一切皆为对象,对象具有属性和行为。
(2) 程序是调用对象方法解决问题。
1 . 2 对象的接口
一切皆为对象,尽管各有特色,但某一系列对象的具有通用的特征和行为,属于一种“类型”(接口),而“类”是那个接口的一种特殊实现方式。接口是面向对象程序设计的基础。
下面让我们以电灯泡为例:
Light lt = new Light();
lt.on();
通过调用Light 对象的on方法实现开灯实际问题。
Light lt = new Light();创建灯对象,It指向这个对象
It.on();调用这个灯对象的打开行为。
1 . 3 实现方案的隐藏
涉足面向对象编程的人员:“类设计者”和“类使用者”,
类只向客户程序员开放有必要开放的东西(接口),其他所有细节都隐藏起来。
接口向使用者提供服务,但却隐藏服务细节。这些代码与那些隐藏起来的数据便叫作“隐藏的实现”。
如果使用者接触服务细节,那么设计者若想修改服务细节,不知道会对使用造成什么影响。
例1、 我要装修房屋,找了一家装修公司,挑选了设计方案,如果我知道设计细节,并且换了更好一些更好的材质,而装修公司是先前的设计方案装修,造成了差价。
例2、 我要装修房屋,找了一家装修公司,挑选了设计方案,如果我不知道设计细节、装修公司可以更换一些合适的材质,让房屋更漂亮,会让我很高兴也让装修公司赢得了信誉。
若接口与实现方法早已隔离开,并分别受到保护,就可放心做到这一点,只要求用户重新链接一下即可。
Java 采用三个显式(明确)关键字以及一个隐式(暗示)关键字来设置类边界:private < protected < friendly < public。
1 . 4 方案的重复使用
重复使用一个类,最简单的办法是仅直接使用那个类的对象。
也能将那个类的一个对象置入一个新类。新类可由任意数量和类型的其他对象构成。这个概念叫作组织,比如“一辆车包含了一个变速箱”。
因为编译器必须对通过继承创建的类加以限制。沿这种思路产生的设计将是非常笨拙的,会大大增加程序的复杂程度。
1 . 5 继承:重新使用接口
我们费尽心思做出一种数据类型后,假如不得不又新建一种类型,令其实现大致相同的功能,那会是一件非常令人灰心的事情。但若能利用现成的数据类型,对其进行“克隆”,再根据情况进行添加和修改,情况就显得理想多了。“继承”正是针对这个目标而设计的。
继承尽管private 成员被隐藏起来,但更重要的是,它复制了基础类的接口。这意味着衍生类具有与基础类相同的类型!
为真正理解面向对象程序设计的含义,首先必须认识到这种类型的等价关系。
1 . 5 . 1 改善基础类
改变基础类一个现有函数的行为。我们将其称作“改善”那个函数。为改善一个函数,只需为衍生类的函数建立一个新定义即可。我们的目标是:“尽管使用的函数接口未变,但它的新版本具有不同的表现”。 ?
1 . 5 . 2 等价与类似关系
与基础类完拥有完全相同的接口。我们完全能够将衍生类的一个对象换成基础类的一个对象!存在一种“等价”关系。但在许多时候,我们必须为衍生类型加入新的接口元素。这种新类型仍可替换成基础类型,但不可在基础类里访问新函数。我们将其称作“类似”关系。需要注意的是类似关系经转换为基类后,不能访问新接口。
1 . 6 多形对象的互换使用
将衍生类的对象当作基础类的一个对象对待,因为它意味着我们只需编写单一的代码,令其忽略类型的特定细节,只与基础类打交道。这样一来,那些代码就可与类型信息分开。所以更易编写,也更易理解。
//处理图形的一个方法
void doStuff(Shape s) {
s.erase();
// ...
s.draw();
}
Circle c = new Circle();
Triangle t = new Triangle();
Line l = new Line();
doStuff(c);
doStuff(t);
doStuff(l);
我们将这种把衍生类型当作它的基本类型处理的过程叫作“Upcasting”(上溯造型)。这是避免去调查准确类型的一个好办法,知道传进来的是个shape,那么就可以调用shape的接口。
注意
1如果子类添加了新的接口将不能被使用。
2我们在重写父类方法时,不要改变其本质,例如圆的erase()其实现改为画一条线,想想上面的代码会怎样?
1 . 6 . 1 动态绑定
当Java编译器为 doStuff()编译代码时,它知道要操作类型是Shape,在运行时 Circle,Square,Line被正确的调用了。这是怎么做到的呢?
这种情况就叫作“多形性”(Polymorphism),实现多形性的方法叫作“动态绑定”。编译器和运行期系统会负责对所有细节的控制;我们只需知道会发生什么事情,如何利用它帮助自己设计程序。
1 . 6 . 2 抽象的基础类和接口
当基础类只为自己的衍生类提供接口,不想其他任何人创建其对象,只用于upcasting,以使用其接口。为达到这个目的,需要把那个类变成“抽象”的,编译器不允许常见抽象类的对象。接口将抽象类的概念更延伸了一步,它完全禁止了所有的函数定义。
注意,应该严格限制类使用者的权限,只开发必要接口,这样有利于类设计者以后的维护。
------解决方案--------------------------------------------------------
连载??????
------解决方案--------------------------------------------------------
看见这些东西我就头晕,都答应别人要好好看thinking in Java了,可是看到那么多汉字就害怕
------解决方案--------------------------------------------------------
期待下集。
------解决方案--------------------------------------------------------
连载??????
------解决方案--------------------------------------------------------
jfjfjf
------解决方案--------------------------------------------------------
不错,给楼主鼓励下
------解决方案--------------------------------------------------------
------解决方案--------------------------------------------------------