OOP:Object-oriented Programming,面向对象程序设计。
1.1 抽象过程
- 万物皆对象。理论上讲,你可以抽取待求解问题的任何概念化构件,将其表示为程序中的对象
- 程序是对象的集合,它们通过发送消息(即调用)来告知彼此所要做的。
- 每个对象都有自己的由其他对象所构成的存储。理解为:可以通过创建包含有现有对象的包的方式来创建新类型的对象。
- 每个对象都拥有其类型。理解为:这里的类型为java代码中的class,即每个对象都是某个类(class)的一个实例。
- 某一特定类型的所有对象都可以接受同样的消息。即继承。
Booch对对象提出了一个更加简洁的描述:对象具有状态(每个对象都可以拥有内部数据,它们给出了该对象的状态)、行为(方法)和标识(每个对象在内存中都有一个唯一的地址)。
1.2 每个对象都有一个接口
在程序执行期间具有不同的状态而其他方面都相似的对象会被分组到对象的类中,这就是关键字class的由来。
因为类描述了具有相同特性(数据元素)和行为(功能)的对象集合,所以一个类实际上就时一个数据类型。
每个对象都只能满足某些请求,这些请求由对象的接口(interface)所定义,决定接口的便是类型。即接口确定了对某一特定对象所能发出的请求。例如:
Light it = new Light();
it.on()
Light:类型、类
it:特定的Light对象
new Light():创建该类型的新对象
it.on():发送消息请求
1.3 每个对象都提供服务
将对象想象为“服务提供者”的好处:
- 有助于开发或者理解一个程序设计
- 有居于提高对象的内聚性。在良好的面向对象设计中,每个对象都可以很好地完成一项任务,但是它不试图做更多的事情。
1.4 被隐藏的具体实现
访问控制的原因:
- 让客户端程序员无法触及他们不应该触及的部分;
- 允许库设计者可以改变类内部的工作方式而不用担心会影响到客户端程序员
访问控制关键字:
- Public:任何人都可以用;
- Private:除类型创建者和类型的内部方法之外的任何人都不能访问;
- Protected:与private作用相当,差别仅在于继承的类可以访问protected的成员,但不能访问private的成员;
- 包访问权限:一种默认的访问权限,当没有使用前面三种任何访问指定词时,它将发挥作用。这种权限下,类可以访问在同一个包中的其他类的成员,但是在包之外,这些成员如同指定了private一样。
1.5 复用具体实现
新的类可以由任意数量、任意类型的其他对象以任意可以实现新的类中想要的功能的方式所组成。使用现有的类合成新的类,这种概念被称为组合(composition),如果组合是动态发生的,那么它通常被称为聚合(aggregation)。组合经常被视为has-a(拥有)关系。
组合带来了极大的灵活性。新类的成员对象通常被声明为private。
组合可以在运行时修改这些成员对象,以实现动态修改程序的行为。而继承不具备这样的灵活性,因为编译器必须对通过继承而创建的类施加编译时的限制。
1.6 继承
类型不仅仅只是描述了作用于一个对象集合上的约束条件,同时还有与其他类型之间的关系。
当继承现有类型时,也就创造了新的类型。这个新的类型不仅包括现有类型的所有成员,而且更重要的是它复制了基类的接口。也就是说,所有发送给基类对象的消息同时也可以发送给导出类对象。这也就意味着导出类与基类具有相同的类型。
有两种方法可以使基类和导出类产生差异:
- 在导出类中添加新方法(is-like-a);
- 改变现有基类的方法,即覆盖(overriding)基类中的方法(is-a)
1.7 伴随多态的可互换对象
在处理类型的层次结构时,经常想把一个对象不当做它所属的特定类型来对象,而是将其当做其基类的对象来对待(泛化)。在试图将到处类型的对象当作其泛化基类型对象来看待时(把圆形看作是几何形),存在一个问题:编译器是不可能知道应该执行哪一段代码的。JAVA是如何解决这个问题的呢?
一个非面向对象编程的编译器产生的函数调用会引起所谓的前期绑定。这么做意味着编译器将产生对一个具体函数名字的调用,而运行时将这个调用解析到将要被执行的代码的绝对地址。然而在OOP中,程序直到运行时才能确定代码的地址,所以当消息放松到一个泛化对象时,必须采用其他的机制。
为了解决这个问题,面向对象程序设计语言使用了后期绑定的概念。当向对象发送消息时,被调用的代码直到运行时才能确定。编译器确保被调用方法的存在,并对调用参数和返回值执行类型检查(无法提供此类保证的语言被称为是弱类型的),但是并不知道将要被执行的确切代码。
为了执行后期绑定,Java使用了一小段特殊的代码来替代绝对地址调用。这段代码使用在对象中存储的信息来技术方法体的地址(参考第八章)。这样,根据这一小段代码的内容,每一个对象都可以具有不同的行为表现。当向一个对象发送消息时,该对象就能够知道对这条消息应该做些什么了。
在某些语言中,必须明确地声明希望某个方法具备后期绑定属性所带来的灵活性(C++使用virtual关键字来实现)。在这些语言中,方法在默认情况下不是动态绑定的。而在Java中,动态绑定是默认行为,不需要添加额外的关键字来实现多态。
笔记:多态有两种实现方式,一种是使用继承重写(overriding),另一种是重载(overloading)。
1.8 单根继承结构
在Java中,所有的类最终都继承自单一的基类:Object。
在单根继承结构中的所有对象都具有一个共用接口,所以它们归根到底都是相同的基本类型。这样保证了所有对象都具备某些功能。
1.9 容器
容器:用来存储容纳相同类型对象的构件。比如在java中,具有满足不同需要的各种类型的容器,如List、Map、Set、堆、栈、树等等。
从设计的观点来看,java是单根继承结构,只需要一个Object容器就可以了,为什么要设计不同类型的序列呢?原因有两个:
- 不同容器提供了不同类型的接口和外部行为。
- 不同的容器对于某些操作具有不同的效率。比如ArrayList(查询数据效率高)和LinkedList(插入数据效率高)。
1.9.1 参数化类型
Java SE5出现之前,容器存储的对象都只具有Java中的通用类型:Object。这使得容器容易被复用,但同时也带来了问题,存储时的向上转型(丢失其身份,尽管是安全的)和取回时的向下转型(运行时异常,不安全),且向下转型和运行时的检查需要额外的程序运行时间,也需要程序员付出更多的心血。
为了解决这个问题,Jave SE5引入了参数化类型机制。参数化类型就是一个编译器可以自动定制作用于特定类型上的类,也被称为范型。一对尖括号,中间包含类型信息。比如:
ArrayList<Shape> shapes =new ArrayList<String>();
1.10 对象的创建和生命期
对象的创建有两种方式:
- 为了追求最大的执行速度,牺牲其灵活性,即对象的存储空间和生命周期在编程时确定,这可以通过将对象置于堆栈(它们有时被称为自动变量(automatic variable)或限域变量(scoped variable))的静态存储区域内来实现。如C++。
- 在被称为堆(heap)的内存池中动态的创建对象。在这种方式中,知道运行时才知道需要多少对象,它们的生命周期如何,以及它们的具体类型时什么。因为存储空间是在运行时被动态管理的,所以需要大量的时间在堆中分配存储空间,这可能要远远大于在堆栈中创建存储空间的时间。如Java。
关于生命周期,对于运行在堆栈上创建对象的语言,编译器可以确定对象的存活时间,并可以自动销毁。然而,如果是在堆上创建对象,编译器就会对它的生命周期一无所知。Java提供了被称为“垃圾回收器”的机制,它可以自动发现对象何时不再被使用,并继而销毁它。
1.11 异常处理:处理错误
异常处理将错误处理直接置于编程语言中,有时甚至置于操作系统中。异常是一种对象,它从出错被“抛出”,并被专门设计用来处理特定类型错误的相应的异常处理器“捕获”。异常提供了一种从错误状况进行可靠性恢复的途径。
在Java中,一开始就内置了异常处理,而且强制你必须使用它。它是唯一可接受的错误报告方式。如果没有编写正确的处理异常的代码,那就就会得到一条编译时的出错消息。
1.12 并发编程
把问题切分成多个可独立运行的部分(任务),从而提高程序的响应能力。在程序中,这些彼此独立运行的部分称之为线程。
通常,线程只是一种为单一处理器分配执行时间的手段。但是如果操作系统支持多处理器,那么每个任务都可以被指派给不同的处理器,实现真正的并行,从而提高处理速度。
1.13 Java与Internet
1.13.1 Web是什么
1. 客户端/服务器计算技术
服务器:信息存储池、用于分发信息的软件以及信息与软件所驻留的机器或机器群被总称为服务器。
客户机:驻留在用户机器上的软件与服务器进行通信,以获取信息、处理信息,然后将它们显示在客户机的用户机器上。
2.Web是一台巨型服务器
Web实际上就是一个巨型客户/服务器系统,但稍微差一点,因为所有的服务器和客户机都同时共存于一个网络中。
1.13.2 客户端编程
1. 插件
定义:下载一段代码,并将其插入到浏览器中适当的位置,以此来为浏览器添加新功能。
缺点:编写插件不是件轻松的事,也不是构建某特定网站的过程中所要做的事情。
价值:它允许专家级的程序员不需要经过浏览器生产厂商的许可,就可以开发某种语言扩展,并将它们添加到服务器中
2. 脚本语言
定义:使用某种脚本语言,可以将客户端程序的源代码直接嵌入到HTML页面中,解释这种语言的插件在HTML页面被显示时自动激活。
缺点:代码会暴露给任何人去浏览(窃取)。
优点:脚本语言易于理解。
3.Java
定义:通过applet以及使用Java Web Start来进行客户端编程的。
优点:Java是一种功能强大、安全的、跨平台的、国际化的编程语言,而且还在不断的被扩展,以提供更多的语言功能和类库。
缺点:安装Java运行时环境(JRE)所必需的10MB带宽对于一般的用户来说过于恐怖了。
4. 备选方案:Macromedia的Felx
5. .NET和C#
挑战:跨平台
6. Internet与Intranet
Intranet: 当Web技术仅限用于特定公司的信息网络时,它就被称为Intranet(企业内部网)。在安装升级程序时所浪费的时间是迁移到浏览器方式上的最主要的原因。