本人的笔记风格是,将书中的重要知识点摘抄出来,若是是特别转弯的话,本人会用本身的理解进行说明。从如今开始讲读书笔记一篇一篇的抛出来,供你们参阅学习讨论,若是错误的地方,请批评指正。首先是《Java编程思想》。java
“咱们之因此将天然界分解,组成各类概念,并按其含义分类,主要是由于咱们是整个口语交流社会共同遵照的协定的参与者,这个协定以语言的形式固定下来……除非同意这个协定中规定的有关语言信息的组织和分类,不然咱们根本没法交谈”程序员
——Benjamin Lee Whorf(1897~1941)数据库
(本人很是喜欢这段话,就摘了出来,完美的诠释了语言对于人类的意义于做用。)编程
计算机革命起源于机器,所以,编程语言的产生也始于对机器的模仿。小程序
本章将介绍包括开发方法概述在内的OOP(Object-oriented Programming)的基本概念。数组
全部编程语言都提供抽象机制。(我的认为,抽象很重要,这是一我的进入编程行当的基础,若是没有想象和联想的能力,建议你仍是不要从事编程行业了,否则会很吃力,或许转个行业对你来讲会很好!)浏览器
程序员必须创建起在机器模型和实际待解决问题的模型之间的关联。创建这种映射是费力的,并且这不属于编程语言所固有的功能,这使得程序难以编写,而且维护代价高昂,同时也产生了做为副产物的整个“编程方法”行业。(这一句话就说明了抽象的重要性。)安全
另外一种对机器建模的方式就是只针对待解决问题建模。(简化工做的开始)服务器
面向对象方式经过向程序员提供表示问题空间中的元素的工具而更近了一步。咱们将问题空间中的元素及其在解空间中的表示称为“对象”。(若是没有想象和联想,这一句话很难理解。)网络
Alan Kay曾总结了第一个成功的面向对象语言——Smalltalk的五个基本特性:
1.万物皆为对象。
2.程序是对象的集合,它们经过发送消息来告知彼此索要作的。
3.每一个对象都有本身的由其余对象所构成的存储。
4.每一个对象都拥有其类型。
5.某一特定类型的全部对象均可以接收一样的消息。
此语言也是Java所基于的语言之一。
Booch对对象提出了一个更加简洁的描述:对象具备状态、行为和标识。
对象的状态:内部提供的数据。
对象的行为:对象内部的方法。
对象的标识:对象在内存中有一个惟一的内存地址。用于区分不一样的对象。
(我的理解,其实对象就是一个事物在程序中的一个缩影,引用就至关于给对象起个名字。名字能够随时更改,可是对象自己性质不会改变。能够先将一个对象局限性的理解为一我的,完全理解以后,再扩大的想象,将它类比为全部你能类比的东西。)
全部的对象都是惟一的,但同时也是具备相同的特性和行为的对象所归属的类的一部分。程序中使用基本关键字class来引入新的类型。事实上,全部的面向对象程序设计语言都是用class这个关键字来表示数据类型。
建立抽象数据类型(类)是面向对象程序设计的基本概念之一。
类描述了具备相同特性和行为的对象集合,一个类实际上就是一个数据类型。
面向对象方法并非仅局限于构建仿真程序。面向对象技术的应用确实能够将大量的问题很容易的降解为一个简单的解决方案。
事实上,面向对象程序设计的挑战之一,就是在问题空间的元素和解空间的对象之间建立一对一的映射。
每一个对象都只能知足某些请求,这些请求由对象的接口(interface)所定义,决定接口的即是类型。
接口肯定了对某一特定对象所能发出的请求。可是,在程序中必须有知足这些请求的代码。这些代码与隐藏的数据一块儿构成了实现。
建立一个对象的方式:
定义这个对象的“引用”(It),而后调用new方法来建立该类型的新对象。为了向对象发送消息,须要声明对象的名称,并以圆点符号连接一个消息请求。
例如:
String str = new String();//建立对象 str.toString();//发送消息请求
下图是UML(Unified Modelling Language,统一建模语言)形式的图,每一个类都用一个方框表示,类名在方框的顶部,你所关心的任何数据成员都描述在方框的中间部分,方法在方框的底部。一般只有类名和公共方法被展现于UML设计图中。
当正在试图开发或者理解一个程序设计时,最好的方法之一就是将对象想象为“服务提供者”。程序自己将向用户提供服务,它将经过调用其余对象提供的服务来实现这一目的。你的目标就是去建立可以提供理想的服务来解决问题的一系列对象。
将对象看做是服务提供者还有一个附带的好处:它有助于提升对象的内聚性。高内聚是软件设计的基本质量要求之一:这意味着一个软件构件的各个方面“组合”的很好。
将对象做为服务提供者看待是一件维达的简化工具,这不只仅在设计的过程当中很是有用,在其余人理解和重用你的代码时变得简单。
程序开发人员按照角色分为类建立者和客户端程序员。(我的理解为:架构师和普通开发人员)
客户端程序员的目标是收集各类用来实现快速应用开发的类。
类建立者的目标是构建类,这种类只向客户端程序员暴露必须的部分,而隐藏其余部分。隐藏的部分一般表明对象内部脆弱的部分,它们很容易被粗心或者不知内情的客户端程序员所毁坏,将此隐藏能够减小bug。
在任何相互关系中,具备关系所涉及的各方都遵照的边界是十分重要的事情。访问控制的第一个存在缘由就是让客户端程序员没法触及他们不该该触及的部分。访问控制的第二个存在缘由就是容许库设计者能够改变类内部的工做方式而不用担忧会影响到客户端程序员。
Java用三个关键字在类的内部设定边界:public、private、protected。
public表示紧随其后的元素对任何人都是可用的。(最大权限)
private表示除了类型建立者和类型的内部方法以外的任何人都不能访问的元素。(最小权限)
protected表示继承的类能够访问。
Java还有一种默认的访问权限,不使用任何关键字,这种权限一般被称为包访问权限,只能同包的类能够互相访问其元素,包外的类访问不了包内这种权限的类元素。
代码复用是面向对象程序设计语言所提供的最了不得的优势之一。
使用现有的类合成新的类被称为组合(composition),若是组合是动态发生的,那么它一般被称为聚合(aggregation)。组合一般被视为“has-a”的关系。
组合带来了极大的灵活性,在创建新类时,应该首先考虑组合。
对象这种概念,自己就是十分方便的工具,使得你能够经过概念将数据和功能封装到一块儿,所以能够对问题空间的观念给出恰当的表示,而不用受制于必须使用底层机器语言,这些概念用关键字class来表示,它们造成了编程语言中的基本单位。
经过继承能够达到复制起因类并加以改造(添加和修改)建立出新类。原有类被称做基类、超类或者父类,新建立的类被称做导出类、继承类或者子类。
类型不只仅只是描述了做用于一个对象集合上的约束条件,同事还有与其余类型之间的关系。
继承使用基类型和导出类型的概念表示了这种类型之间的类似性。一个基类型包含其导出类型所共享的特性和行为。能够建立一个基类型来表示系统中某些对象的核心概念,从基类型中导出其余类型,来表示此核心能够被实现的各类不一样方式。
例以下图:
当继承现有类型时,也就是建立了新的类型。这个新的类型不只包括现有类型的全部成员(尽管private成员被隐藏了起来,而且不可访问),并且更重要的是它复制了基类的接口。也就是说,全部能够发送给基类对象的消息同时也能够发送给导出类对象。这就意味着处处类与基类具备相同的类型。
因为基类和导出类具备相同的基础接口,因此伴随此接口的一定有某些具体实现。当对象接收到特定的消息时,必须有某些代码去执行。若是只是简单的继承,而不作任何改变的话,这就意味着导出类与基类拥有相同的类型和相同的行为,这样作是没有意义的。
有两种方法可使基类和导出类产生差别:
一是直接在导出类中添加新方法。二是改变现有基类的方法的行为,这被称做覆盖(overriding)。
若是继承只覆盖基类的方法,就意味着导出类和基类是彻底相同的类型,就能够用一个导出来对象来彻底替代一个基类对象,这能够被视为纯粹替代,一般称做替代原则。咱们常常将这种状况下的基类与导出类之间的关系成为is-a关系。
判断是否继承,就是要肯定是否能够用is-a来描述类之间的关系,并使之具备实际意义。
若是在导出类型中添加新的接口元素,这样也就扩展了接口。这个新的类型仍然能够替代基类,可是这种替代并不完美,由于基类没法访问新添加的方法。这种状况咱们能够描述为is-like-a关系。新类型具备旧类型的接口,可是它还包含其余方法,因此不能说它们彻底相同。
在处理类型的层次结构时,常常想把一个对象不看成它所属的特定类型来对待,而是将其看成其基类的对象来对待。这使得人们能够编写出不依赖于特定类型的代码。
这样的代码时不会受添加新类型影响的,并且添加新类型是扩展一个面向对象程序以便处理新状况的最经常使用方式。经过导出新的子类型而轻松扩展设计的能力是对改动进行封装的基本方式之一。这种能力能够极大的改善咱们的设计,同时也下降然间维护的代价。
在试图将导出类型的对象看成其泛化(generic)基类型对象来看待时,仍然存在一个问题:代码执行的时候到底该调用谁?
一个非面向对象编程的编译器产生的函数调用会引发所谓的前期绑定。前期绑定就是编译器将产生对一个具体函数名字的调用,而运行时将这个调用解析到将要被执行的代码的绝对地址。
为了解决上述问题,面向对象程序设计语言使用了后期绑定的概念。后期绑定就是当向对象发送消息时,被调用的代码知道运行时才能肯定。
编译器确保被调用方法的存在,并对调用参数和返回值执行类型检查,可是并不知道将被执行的确切代码。没法提供此类保证的语言被称为弱类型语言。
为了执行后期绑定,Java使用一小段特殊的代码来代替聚堆地址调用。这段代码使用在对象中存储的信息来计算方法体的地址。
Java中动态绑定是默认行为,不须要添加额外的关键字来实现多态。
把导出类看作是其基类的过程称为向上转型(upcasting)。
一个面向对象程序确定会在某处包含向上转型,由于这是将本身从必须知道确切类型中解放出来的关键。
在Java中,全部的类最终都继承自单一的基类,这个终极基类的名称就是Object。
单根继承的好处:
在单根继承结构中的全部对象都具备一个共用接口,因此它们归根结底都是相同的基本类型。
单根继承结构保证全部对象都具有某些功能。Java中Object类的方法就能够看作是对象都具有的功能。
单根继承结构使垃圾回收器的实现变得容易得多。
建立另外一种对象类型,这种新的对象类型持有对其余对象的引用,这一般被称做容器,固然也包括数组。
好的OOP语言都有一组容器,它们做为开发包的一部分。Java在其标准类库中也包含有大量的容器。在某些类库中,一两个通用容器足够知足全部的需求,可是在其余类库中,具备知足不一样需求的各类类型的容器。例如:List、Map、Set以及诸如队列、树、堆等更多的构件。
须要针对容器进行选择有两个缘由:
Java SE5的重大变化之一就是在增长了参数化类型,在Java中称为泛型。一对尖括号,中间包含类型信息,经过这些特征就能够识别对泛型的使用,例如:
ArrayList<String> strList=new ArrayList<String>();
泛型规定了容器中存储的数据类型,这样就避免了转型带来的麻烦。
Java中彻底采用动态内存分配方式。每当须要建立新对象时,使用new关键字累构件对象的动态实例。
动态方式是在被称为堆(heap)的内存池中动态的建立对象。动态方式能够在须要对象的时候直接在堆中建立。由于存储空间是是正赛运行时被动态管理的,因此须要大量的时间在堆中分配空间。
动态方式有一个通常性的逻辑假设:对象趋向于变的复杂,因此查找和设防存储空间的开销不会对对象的建立形成重大冲击。
动态方式所带来的更大的灵活性正是解决通常化编程问题的要点所在。
Java提供了被称为“垃圾回收器”的机制,它能够自动发现对象什么时候再也不被使用,并继而销毁它。Java的垃圾回收器被设计用来处理内存释放问题。
自从编程语言问世以来,错误处理就诗中是最困难的问题之一。
异常处理将错误处理直接置于编程语言中,有时甚至置于操做系统中。异常是一种对象,它从出错地点被“抛出”,并专门设计用来处理特定类型错误的相应的一场处理器“捕获”。异常不能被忽略,因此保证必定会在某处获得处理。最后须要指出的是:异常提供了一种从错误情况进行可靠恢复的途径。如今再也不是只能退出程序,你能够常常进行校订,并恢复程序的执行,这些都有助于编写出更健壮的程序。
Java一开始就内置了异常处理,并且强制你必须去使用它。它是惟一可接受的错误报告方式。若是没有编写正确的处理异常的代码,那么就会获得一条编译时的出错消息。这种有保障的一致性有时会使得错误处理很是容易。
异常处理不是面向对象的特征,异常处理在面向对象语言出现以前就已经存在了。
在计算机编程中有一个基本概念,就是在同一时刻处理多个任务的思想。
并发:把问题切分红多个可独立运行的部分(任务)。
在程序中这些彼此独立运行的部分称之为线程。线程只是一种为单一处理器分配执行时间的手段。若是操做系统支持多处理器,那么每一个任务均可以被指派给不一样的处理器,而且他们是在真正的并行执行。
并发存在一个隐患:共享资源。所以,整个执行过程应该是:某个任务锁定某项资源,完成其任务,而后释放资源锁,使其余任务可使用这项资源。
Java的并发是内置于语言中的,Java SE5已经增添了大量额外的库支持。
Java对于解决传统的单机程序设计问题很是有用,更重要的是,它解决了在万维网(WWW)上的程序设计问题。
要理解Web是什么就必须先理解客户/服务器系统。
客户/服务器系统的核心思想是:系统具备一个中央信息存储池(central repository of information),用来存储某种数据,它一般存在于数据库中,大家能够根据须要将它分发给某些人员或机器集群。
信息存储池、用于分发信息的软件以及信息与软件所驻留的机器或集群被总称为服务器。
保证一个客户插入的新数据不会覆盖另外一个客户插入的新数据,也不会在将其添加到数据可的过程当中丢失,这被称为事务处理。
性能问题:可能在任意时刻都有成百上千的客户向服务器发出请求,因此任何小的延迟都会产生重大影响。为了将延迟最小化,程序员努力减轻处理任务的负载,一般是分散给客户端机器处理,但有时也会使用所谓的中间件将负载分散给在服务器端的其余机器。(中间件也被用来提升可维护性。)
Web实际上就是一个巨型客户/服务器系统。
Web浏览器包含了这样的概念:一段信息不经修改就能够在任意型号的计算机上显示。
浏览器只是一个观察器,所以它甚至不能执行最简单的计算任务。另外一方面,它倒是安全的,由于它在你的本地机器上不会执行任何程序,而这些程序有可能包含bug和病毒。
为了加强浏览器的功能,人们采用了各类不一样的方法。首先,图形标准获得了加强,使得在浏览器中能够播放质量更好的动画和视频。
客户端编程:引入在客户端浏览器中运行程序的能力。
Web最初的“服务器-浏览器”设计是为了可以提供交互性的内容。但其实交互性彻底由服务器提供。服务器产生静态页面,提供给只能解释并显示它们的客户端浏览器。
基本的HTML(HyperText Markup Language,超文本标记语言)包含有简单的数据收集机制:文本输入框、复选框、单选框、列表和下拉式列表以及按钮——它只能被编程来实现复位表单上的数据或提交表单上的数据给服务器。
这种提交动做经过全部的Web服务器都提供的通用网关接口(common gateway interface,CGI)传递。提交内容会告诉CGI应该如何处理它。实际上你能够经过CGI作任何事。然而构建于CGI程序之上的网站可能会迅速变得过于复杂而难以维护,并同时产生响应时间过长的问题。CGI程序的响应时间依赖于所必须发送的数据量的大小,以及服务器和Internet的负载,此外启动CGI程序也至关慢。
客户端编程意味着Web浏览器能用来执行任何它能够完成的工做,使得返回给用户的结果更加迅捷,并且使得你的网站更加具备交互性。
客户端编程的问题:它与一般意义上的编程十分不一样,参数几乎相同,而平台不一样。
客户端编程所迈出的最重要的一步就是插件(plug-in)的开发。经过这种方式,程序员能够下载一段代码,并将其插入到浏览器中适当的位置,以此来为浏览器添加新功能。
插件对于客户端编程的价值在于:它容许专家级的程序员不需通过浏览器生产厂商的许可,就能够开发某种语言扩展,并将它们添加到服务器中。所以插件也至关于提供了一个“后门”。
插件引起了浏览器脚本语言(scripting language)的开发。经过使用某种脚本语言,你能够将苦短程序的源代码直接嵌入到HTML页面中,解释这种语言的插件在HTML页面被显示时自动激活。
优势:至关易于理解,能够被快速加载。
缺点:代码会暴露给任何人去浏览。
在Web浏览器内部使用的脚本语言实际上老是被用来解决特定类型的问题,主要是用来建立更丰富、更具备交互性的图形化用户界面(graphic user interface,GUI),脚本语言能够解决客户端编程中所遇到的百分之八十的问题,因此在考虑解决方案的时候应优先考虑脚本语言。
Java不只是一种功能强大的、安全的、跨平台的、国际化的编程语言,并且它还在不断地被扩展,以提供更多的语言功能和类库,可以优雅地处理在传统编程语言中很难解决的问题,例如并发、数据库访问、网络编程和分布式计算。
Java是经过applet以及使用Java Web Start来进行客户端编程的。
applet是只在Web浏览器中运行的小程序,它是做为网页的一部分而自动下载的。当applet被激活时,它便开始执行一个程序,它提供一种分发软件的方法,一旦用户须要客户端软件时,就自动从服务器把客户端软件分发给用户。用户获取最新版本的客户端软件时不会产生错误,并且也不须要很麻烦的从新安装过程。
只要一台计算机有浏览器,且浏览器内置了Java解释器,那么这个程序就能够自动在这台计算机上运行。还能够在数据提交以前作数据校验,减小网络带宽的传输。
实际上,applet并无大规模的应用,有如下几个缘由:
1.安装Java运行时环境(JRE)必须10M带宽。
2.微软没有在IE(Internet Explorer)中包含JRE
那么就须要几个备选方案:
Macromedia的Flex,它容许你建立基于Flash的与applet至关的应用,Flash Player在超过98%的Web浏览器上均可用,因此编程时无需担忧浏览器的相关性。
ActionScript语言是基于ECMAScript的。
曾经,Java applet的主要竞争对手是微软的ActiveX。ActiveX要求客户端必须运行在Windows平台。
.NET平台大体至关于Java虚拟机(JVM)和Java类库,而C#毫无疑问与Java有相似之处。
.NET最受关注的问题就是微软是否容许将它彻底地移植到其余平台。微软宣称这么作没有问题,并且Mono项目已经有一个在Linux上运行的.NET的部分实现,可是还不稳定。
Web是最经常使用的解决客户端/服务器问题的方案,能够解决如下问题:
1.客户端计算机多种型号。
2.安装软件的麻烦。
3.软件升级的麻烦,浏览器方式下的升级是透明的、自动的。
当Web技术仅限于特定公司的信息网络时,它被称为Intranet(企业内部网)。Intranet比Internet提供了更高的安全性,由于能够屋里地控制对公司内部服务器的访问。在Intranet上,你能够对本身的代码质量负责,而且在发现bug以后能够修复它们。
当面对各类使人眼花缭乱的解决客户端编程问题的方案时,最好的方法就是进行性价比分析。认真考虑问题的各类限制,而后思考那种解决方案能够成为最短的捷径。
Java取得巨大成功的因素之一就是服务器端编程。
涉及到对数据库的修改,这些数据可请求必须经过服务器端的某些代码来处理,这就是所谓的服务器端编程。
基于Java的Web服务器使用Java编写被称为servlet的程序来实现服务器端编程。servlet及其衍生物JSP,是许多开发网站的公司迁移到Java上的两个主要的缘由,尤为是由于他们消除了处理具备不一样能力的浏览器时所遇到的问题。
服务器端编程的具体介绍请看《企业Java编程思想》。
编写良好的Java程序一般比过程型程序要简单得多,并且也易于理解得多。
使用Java只须要关心如下两部份内容的定义:用来表示问题空间概念的对象,以及发送给这些对象的用来表示在此空间内的行为的消息。
对于设计良好的程序,经过阅读它就能够很容易地理解其代码。一般,其代码也会少不少,由于许多问题均可以经过重用现有的类库代码而获得解决。
我的总结
此章内容,将Java从头至尾大体上介绍了一遍,若是是初学者,确定会很懵,只有对Java有必定了解的人,才能有些理解,对初学者的建议是忽略此章,从第二章开始学习,最后,再来看此章节。