对象导论
抽象过程
所有编程语言都提供抽象机制。
万物皆为对象
程序是对象的集合,它们通过发送消息来告知彼此所要做的。
每个对象都有自己的由其他对象所构成的存储
每个对象都拥有其类型
某一特定类型的所有对象都可以接受同样的消息
对象具有状态,行为和标识
每个对象都有一个接口
怎样才能获取有用的对象?必须有某种方式产生对对象的请求,是对象完成各种任务,如完成一笔交易,在屏幕上画图,打开开关等。每个对象都只能满足某些请求,这些请求有对象的接口(interface)所定义,决定接口的便是类型。
以电灯泡为例来做一个简单的比喻:
1 | Light lt = new Litght(); |
接口确定了对某一特定对象所能发出的请求。
上例中,类型/类的名称是Light,特定的Light对象的名词是It,可以向Light对象发出的请求是:打开它,关闭它,将它调亮,将它调暗。你以下列方式创建了一个Light对象:定义这个对象的‘引用’(It),然后调用new方法来创建该类型的新对象。为了向对象发送消息,需要声明对象的名称,并以圆点符号连接一个消息请求。
每个对象都提供服务
程序本身将向用户提供服务,他将通过调用其他对象提供的服务来实现这一目的。
被隐藏的具体实现
java用三个关键字在类的内部设定边界,public,private,protected
java还有一种默认的访问权限,当没有使用前面提到的任何访问指定词时,它将发挥作用。这种权限通常被称为包访问权限
复用具体实现
代码复用是面向对象程序设计语言所提供的的最了不起的优点之一。
继承
当继承现有类型时,也就创造了新的类型。这个新的类型不仅包括现有类型的所有成员(尽管private成员被隐藏,并且不可访问),而且更重要的是它复制了基类的接口。也就是说,所有可以发送给基类对象的消息同时也可以发送给导出类对象。导出类与基类具有相同的类型。
一个圆形也是一个几何形。
有两种方法可以使基类与导出类产生差异。
直接在导出类中添加新方法,这个新方法并不是基类接口的一部分。
覆改变现有基类的方法,覆盖。
伴随多态的可互换对象
面向对象程序设计的最重要的妙诀:编译器不可能产生传统意义上的函数调用。
如果用Java来编写一个方法(后面很快你就会学习如何编写):
1 | void doSomething(Shape shape){ |
这个方法可以与任何Shape对话,因此它是独立于任何它要绘制和擦除的对象的其体类型的。
如果程序中其他部分用到了doSomething()方法:
1 | Circle CirCie,new Circle(); |
对doSomething()的调用会白动地正确处理,而不管对象的确切类型。
这是一个相当令人惊奇的诀窍。看看下面这行代码:
doSomething(circle);
当Circle被传入到预期接收Shape的方法中,究竟会发生什么。由于Circle可以被doSomething() 看作是Shape,也就是说,doSomething()可以发送给Shape的任何消息,Circle都可以接收,那么,这么做是完全安全且合乎逻辑的。
单根继承结构
在OOP中,自c++面世以来就己变得非常瞩目的一个问题就是,是否所有的类最终都继承自单一的基类。在java中(事实上还包括除C++以外的所有OOP语言),答案是yes,这个终极基类的名字就是Object。事实证明,单根继承结构带来了很多好处。
在单根继承结构中的所有对象都具有一个共用接口,所以它们归根到底都是相同的基本类型。
容器
这个通常被称为容器(也称为集合,不过Java类库以不同的含义使用“集合”这个术语,所以本书使用“容器”这个词)的新对象,在任何需要时都可扩充自己以容纳你置于其中的所有东西。因此不需要知道将来会把多少个对象置于容器中,只需要创建一个容器对象,然后让它处理所有细节。
对象的创建和生命期
在使用对象时,最关键的问题之一便是他们的生成和销毁方式。每个对象为了生存都需要资源,尤其是内存。当我们不再需要一个对象时,它必须被清理掉,使其占有的资源被释放和重用。
Java完全采用了动态内存分配方式。每当想要创建新对象时,就要使用new关键字来构建此对象的动态实例。
Java提供了垃圾回收器的机制,它可以自动发现对象何时不再被使用,并继而销毁它。
异常处理:处理错误
异常处理将错误处理直接置于编程语言中,有时甚至置于操作系统中。异常是一种对象,它从出错地点被“抛出’,并被专门设计用来处理特定类型错误的相应的异常处理器“捕获”。异常处理就像是与程序正常执行路径并行的、在错误发生时执行的另一条路径。因为它是另一条完全分离的执行路径,所以它不会干扰正常的执行代码。这往往使得代码编写变得简单,因为不需要被迫定期检查错误。
此外,被抛出的异常不像方法返回的错误值和方法设置的用来表示错误条件的标志位那样可以被忽略。异常不能被忽略,所以它保证一定会在某处得到处理。
最后需要指出的是:异常提供了一种从错误状况进行可靠恢复的途径。现在不再是只能退出程序,你可以经常进行校正,并恢复程序的执行,这些都有助于编写出更健壮的程序。
Java的异常处理在众多的编程语言中格外引人注目,因为Java一开始就内置了异常处理,而且强制你必须使用它。
并发编程
在计算机编程中有一个基本概念。就是在同一时刻处理多个任务的思想。许多程序设计问题都要求,程序能够停下正在做的工作,转而处理某个其他问题。然后再返回主进程。
有时中断对于处理时间性强的任务是必需的,但是对于大量的其他问题,我们只是想把问题切分成多个可独立运行的部分(任务),从而提高程序的响应能力。在程序中,这些彼此独立运行的部分称之为线程,上述概念被称为“并发”。
总结
你知道过程型语一言看起来像什么样子:数据定义和函数调用。想了解此类程序的含义,你必须忙上一阵,需要通读函数调用和低层概念,以在脑海里建立一个模型。这正是我们在设计过程式程序时,需要中间表示形式的原因。这些程序总是容易把人搞糊涂,因为它们使用的表示术语更加面向计算机而不是你要解决的问题。