java编程思想_对象导论_0103
1.8单根继承结构
java中,所有的类最终都继承自单一的基类,Object。
单根继承中所有对象都具有一个共用接口,归根结底都是相同的基本类型。
单根继承结构保证所有对象都具备某些功能。你可以在每个对象上执行某些基本操作。
单根继承使垃圾回收器的实现变得容易得多,所有对象都保证具有其类型信息,不会因无法确定对象的类型而陷入僵局。
1.9容器
一种对象类型,这种对象类型持有对其他对象的引用。在任何需要时都可扩充自己以容纳你置于其中的所有东西。
Java中各种类型容器:
List:存储序列;
Map:关联数组,建立对象之间的关联;
Set:每种对象类型只持有一个;
以及诸如队列,树,堆栈等更多的构件。
从设计的观点来看,需要一个可以被操作,从而解决问题的序列。
需要对容器有所选择,原因:
①不同容器提供了不同类型的接口和外部行为。
例:堆栈相比于队列就具备不同的接口和行为,也不同于集合和列表的接口和行为。它们之中的某种容器提供的解决方案可能比其他容器要灵活得多。
②不同的容器对于某些操作具有不同的效率。
例:ArrayList和LinkedList,是具有相同接口和外部行为的简单的序列,但某些操作花费的代价不同。
ArrayList中,随机访问元素是一个花费固定时间的操作;
Linkedlist中,随机选取元素需要在列表中移动,代价高昂,访问越靠近表尾的元素,花费的时间越长。
另外,如果想在序列中间插入一个元素,LinkedList的开销比ArrayList要小。
1.9.1参数化类型
在Java SE5出现前,容器存储的对象都只具有Java中的通用类型:Object。
单根继承结构意味着所有东西都是Object类型,所以可以存储Object的容器可以存储任何东西。
使用容器,在其中置入对象引用,稍后还可将它们取回。
由于容器只存储Object,当将对象引用置入容器时,它必须被向上转型为Object,它会丢失其身份。
当把它取回时,就获取了一个对Object对象的引用,而不是对置入时的那个类型的对象的引用。
怎样才能将它变回先前置入容器中时的具有实用接口的对象呢?
向下转型。
向上转型是安全的,例如Circle是一种Shape类型;但是不知道某个Object是Circle还是Shape,除非确切知道所要处理的对象的类型,否则向下转型是不安全的。
向下转型并非是彻底危险的,如果向下转型为错误的类型,就会得到被称为异常的运行时错误。
参数化类型机制:容器知道自己所保存的对象的类型,不需要向下转型。
一个编译器可以自动定制作用于特定类型上的类。例如,使用参数化类型,编译器可以定制一个只接纳和取出Shape对象的容器。
Java SE5,重大改变,增加了参数化类型,泛型。
例,用下列语句来创建一个存储Shape的ArrayList:
ArrayList<Shape> shapes=new ArrayList<Shape>();
1.10对象的创建和生命期
简单的情况:创建了对象,根据需要使用它,然后它应该被销毁。
对象的数据位于何处?怎样控制对象的生命周期?
C++,效率控制。追求最大的执行速度,对象的存储空间和生命周期可以在编写程序时确定,可以通过将对象置于堆栈(自动变量或限域变量)或静态存储区域来实现。
这种方法牺牲了灵活性,因为必须在编写程序时知道对象确切的数量、生命周期和类型。解决一般的问题使用受限。
第二种方式,在被称为堆的内存池中动态地创建对象。
在这种方式中,直到运行时才知道需要多少对象,它们的生命周期如何,以及它们的具体类型是什么。
这些问题的答案只能在程序运行时相关代码被执行的那一刻才能确定。
如果需要一个新对象,可以在需要的时刻直接在堆中创建。
因为存储空间是在运行时被动态管理的,所以需要大量的时间在堆中分配存储空间,这可能要远远大于在堆栈中创建存储空间的时间。
在堆栈中创建存储空间和释放存储空间通常各需要一条汇编指令即可,分别对应将栈顶指针向下移动和将栈顶指针向上移动。创建堆存储空间的时间依赖于存储机制的设计。
动态方式有这样一个一般性的逻辑假设:对象趋向于变得复杂,所以查找和释放存储空间的开销不会对对象的创建造成重大冲击。动态方式所带来的更大的灵活性正是解决一般化编程问题的要点所在。
Java完全采用动态内存分配方式。每当想要创建新对象时,就要使用New关键字来构建此对象的动态实例。
对象的生命周期。对于允许在堆栈上创建对象的语言,编译器可以确定对象存活的时间,并可以自动销毁它。然而,如果是在堆上创建对象,编译器就会对它的生命周期一无所知。在像C++这样的语言中,必须通过编程方式来确定何时销毁对象,这可能会因为不能正确处理而导致内存泄漏。Java提供了被称为“垃圾回收器”的机制,它可以自动发现对象何时不再被使用,并继而销毁它。垃圾回收器非常有用,因为它减少了所必须考虑的议题和必须编写的代码。更重要的是,垃圾回收器提供了更高层的保障,可以避免暗藏的内存泄露问题,这个问题已经使许多C++项目折戟沉沙。
Java的垃圾回收器被设计用来处理内存释放问题(尽管它不包括清理对象的其他方面)。垃圾回收器知道对象何时不再被使用,并自动释放对象占用的内存。这一点同所有对象都是继承自单根基类Object以及只能以一种方式创建对象(在堆上创建)这两个特性结合起来,使得用Java编程的过程较之用C++编程要简单得多,所要做出的决策和要克服的障碍也要少得多。
1.11异常处理:处理错误
大多数错误处理机制的主要问题,它们依赖于程序员自身的警惕性,这种警惕性来源于一种共同的约定,而不是编程语言所强制的。这些机制很容易被忽视。
异常处理将错误处理直接置于编程语言中,有时甚至置于操作系统中。
异常是一种对象,它从出错地点被抛出,并被专门设计用来处理特定类型错误的相应的异常处理器“捕获”。
异常处理,与程序正常执行路径并行的,在错误发生时执行的另一条路径。
异常不能被忽略,它保证一定会在某处得到处理。
异常提供了一种从错误状况进行可靠恢复的途径。现在不再是只能退出程序,你可以经常进行校正,并恢复程序的执行,有助于编写更健壮的程序。
Java内置了异常处理,强制使用。它是唯一可接受的错误报告方式。
如果没有编写正确的处理异常的代码,就会得到一条编译时出错消息。
1.12并发编程
同一时刻处理多个任务。
能够停下正在做的工作,转而处理某个其他问题,然后再返回主进程。
最初,编写中断服务程序来实现。主进程的挂起是通过硬件中断来触发的。难以移植。
把问题切分成多个可独立运行的部分(任务),提高程序响应能力。这些彼此独立运行的部分称之为线程。
并发最常见的例子是用户界面,通过使用任务,用户可以按下按钮后快速得到一个响应,而不用被迫等待到程序完成当前任务为止。
共享资源,
过程:某个任务锁定某项资源,完成其任务,然后释放资源锁,使其他任务可以使用这项资源。
1.13Java与Internet
Java促使计算机编程语言向前迈进了革命性的一步,Java对于解决传统的单机程序设计问题非常有用,同样重要的是,它解决了在万维网上的程序设计问题。
1.13.1 Web是什么
1.客户、服务器计算技术
客户/服务。器系统的核心思想:系统具有一个中央信息存储池,用来存储数据,通常存在于数据库中。可以根据需要将它分发给某些人员或机器集群。
信息存储池的位置集中于中央,它可以被修改,并且这些修改将被传播给信息消费者。
服务器:信息存储池,用于分发信息的软件,信息与软件所驻留的机器或机群被总称为服务器。
驻留在用户机器上的软件与服务器进行通信,以获取信息,处理信息,然后将它们显式在被称为客户机的用户机器上。
为了将延迟最小化,程序员努力减轻处理任务的负载,通常是分散给客户端机器处理,但有时也会使用所谓的中间件将负载分散给在服务器端的其他机器。
2.Web就是一台巨型服务器
web是一个巨型客户/服务器系统,所有的服务器和客户机都同时共存于同一个网络中。