《java编程思想(第四版)》第一章 读书笔记

看点

1~17章必看,18,19,20了解一下,21章,22章pass

第一章 对象导论

介绍背景性和补充性的材料,可先跳过。

1.1 抽象过程

所有语言都提供抽象机制,而且面向对象的方式非常通用。

  1. 万物皆为对象。将对象视为神奇的变量,可以存储数据。抽取问题的任何概念,化为对象。
  2. 程序是对象的集合,通过发送消息来告知彼此所要做的。可以将消息视为某个特定对象的方法的调用请求。
  3. 每个对象都有自己的有其他对象所构成的存储。可以通过穿件包含现有对象的的形式,来创建新的对象(子类)。
  4. 每个对象都拥有其类型。每个对象都是某个类的实例。类的特性就是可以发送什么样的消息它。
  5. 某一特定类型的所有对象都可以接受同样的消息。子类可以接受任何父类类型的消息传递。可替代性,向上转型。
    对象具有状态、行为和标识。这意味着每一个对象都可以拥有内部数据(对象状态)和方法(产生的行为),并且每一个对象都可以唯一地与其他对象区分开来,具体说来就是对每一个对象在内存中都有一个唯一的地址。

1.2 每一个对象都有一个接口

接口确定了对 某一特定对象所能发出的请求。
在这里插入图片描述
类的名称是Light,特定的Light对象的名称是It,可以向Lght对象发出的请求:on,off…

1.3对每个对象都提供服务

将对象想象成 service provider,程序本身将向用户提供service。我们的目标就是创建能够提供理想化的服务来解决问题的一系列现象。——这样想象有助于提高对象的内聚性,也更容易让其他人理解代码。

每个对象都有一个他所能提供的服务的内聚的集合。 一个良好的面向对象设计中,每个对象都可以很好的完成一项任务,而且不用做很多事。

拓展:什么是高内聚、低耦合?

  1. 高内聚:
  2. 低耦合

1.4 被隐藏的具体实现

将开发人员分为类创建者客户端程序员

java用三个关键字在类的内部设定边界:public、private、protected。
public、private、protected区别

1.5复用具体实现

代码复用是面向对象程序设计语言所提供的最了不起的优点之一。
组合(composition):使用现在的类合成新的类。【如“汽车拥有引擎”就是一种组合】
聚合(aggregation):动态发生的组合。

组合带来了极大的灵活性。新类的对象通常都被声明为private。让你在不受干扰的情况下修改这些成员,并实现动态修改程序的行为。

建立新类时应该首先考虑组合,这使得设计变得更加清晰,而继承使其变得复杂。

1.6 继承

对象是十分方便的工具,使得你可以通过抽象概念将数据和功能封装到一起。但是这样还是有很多麻烦:在创建了一个类之后,即使另一个新类与其具有相似的功能,还是得重新创建一个新类。利用继承就可以复制一个类,然后通过修改和添加这个副本来创建新类。

两个方法使基类和导出类产生差异。

  1. 直接在导出类中添加新方法。
  2. 改变现有的基类的方法——覆盖(coverriding)。

1.6.1 “是一个”与“像一个”的关系


(略)

伴随多态的客户换对象

添加新类型是扩展一个面向对象程序的常用方式。通过导出新的子类型而轻松扩展设计的能力是对改动进行封装的基本方之一,这种能力可以大大改善设计,降低软件维护的成本。
但是这存在一个问题:如果某个方法要让泛化几何形状绘制自己、让泛化交通工具行驶等,那么编译器就不可能知道自己该执行那一段代码。那么该怎么办呢?
在这里插入图片描述
在上图中,BirdController对象仅仅处理泛化的Bird对象,而不了解它们的确切类型。这样做不需要编写特别的代码来判定需要处理的Bird对象的确切类型或其行为。当move()方法被调用时,即便忽略Bird的具体类型,也会产生正确的行为,鹅走、游泳、飞,企鹅走、游泳。

首先编译器不可能产生传统意义上的函数调用。一个非面向对象编程的编译器产生的函数调用会引起所谓的前期绑定:编译器将产生对一个具体函数名字的调用,而运行时将这个调用解析到将要被执行的代码的绝对地址,然而在OOP(面向对象程序设计)中,程序知道运行时才能确定代码的地址,所以当消息发送到一个泛化对象时,必须采用其他的机制。

为了解决这个问题,面向对象程序设计语言使用了后期绑定的概念:当对象发送消息时,被调用的代码直到运行时才能确定。为了执行后期绑定,JAVA使用一小段特殊的代码来代替绝对地址的调用。这段代码使用对象中存储的信息来计算方法体的地址(详见第八章)。

在某些语言当中,必须声明希望某个方法具备后期绑定带来的灵活性。但是java中,动态绑定是默认行为,不需要添加额外的关键字。

把导出类看做基类的过程被称为向上转型(upcasting),一个面向对象的程序肯定会在某处向上转型,因为这样是知道确切类型的关键。

在这里插入图片描述
正是多态才能使得事情总是被正确的处理。即使设计向上转型,对象也能够知道执行什么样的正确的行为。

1.8 单根继承结构

在java中是单根的继承结构,终极基类是Object。
好处:

  1. 所有的对象都具有一个公共的接口。
  2. 保证所有对象都具有某些功能。所有对象都可以很容易地在堆上创建,参数传递也能得到极大的简化。
  3. 使垃圾回收器的实现变得容易得多。??

1.9 容器

容器也称”集合“,java中的集合和其他语言不同。
List:储存序列
Map:也成为关联数组,用于建立对象之间的关联
Set:每种对象类型只持有一个
以及队列、树、堆栈等更多的构件。

从设计的观点来看,真正需要的只是一个可以被操作,从而解决问题的序列。
不同的容器提供了不同的接口和外部行为。
不同的容器对于某些操作具有不同的效率。
如:ArrayList和LinkedList…我们可以在一开始使用LinkedList构建程序,而在优化系统性能时改用ArrayList。

1.9.1 参数化类型

在Java SE5出现之前,容器储存的对象只有Java中的通用类型:Object。该容器可以储存任何东西,这导致容器很容易被服用。

这会导致当将对象引用置入容器时,它必须被向上转型为Object,因此他会丢失其原有的类型。当把它取回时,就获取了一个对Object对象的引用,而不是对置入时的那个类型的对象的引用。

这又再度到了向下转型。但除非确切的知道要处理的对象类型,否则向下转型是很不安全的,如果向下转型为错误的类型,就会出现异常的运行时错误,并且向下转型和运行时的检查需要额外的程序运行时间,也需要程序员付出更多的成本。

这时,就需要用到被称为参数化类型机制的解决方案。参数化类型就是一个编译器可以自动定制作用于特定类型上的类。例如:通过使用参数化类型,编译器可以定制一个只接纳和取出Shape对象的容器。Java SE5的重大更新就是增加了参数化类型,被称为 “泛型” 。

一对尖括号,中间包含类型信息,通过这些特征就可以识别对泛型的使用。

ArrayList<Shape> shapes = new.ArrayList<Shape>() ; #创建一个储存Shape的ArrayList

1.10 对象的创建和生命期

在使用对象时,最关键的问题之一便是他们的生成和销毁方式。

方式1:C++ 认为效率控制是重要的议题,对象的存储空间和声明周期可以在编写程序时确定,通过将对象置于堆栈或限域对象或静态存储区来实现。这种方式将存储空间分配和释放置于优先考虑的位置。这种方式牺牲了灵活性。因为必须在编程的时候确定对象的数量,生命周期,类型。可以确定存活时间,并自动销毁它。

方式2:在被成为(heap)的内存池中动态地创建对象。储存空间是被动态管理的,这种方式需要大量的时间,远远超过堆栈所需的时间。动态方式对有一个一般性的逻辑假设:对象趋于变得复杂。所以查找和释放存储空间的开销不会对对象的创建造成重大的冲击。它能带来更大的灵活性。对他的生命周期一无所知

Java完全采用了动态内存分配方式。每当想创建新对象时,就要使用new关键词来构建此对象的动态实例。

C++这样的语言中,必须通过编程的方式确定何时销毁对象,不然就会造成内存泄露。而Java提供了“垃圾回收器机制,它可以自动发现对象何时不再使用,并继而销毁它,避免了内存泄漏问题。

1.11 异常处理:处理错误

  1. 异常处理问题始终是最困难的问题之一。设计一个良好的错误处理机制非常困难,许多语言直接忽略这个问题并交给程序库设计者处理,设计者的解决方法通常是忽略此问题。
  2. 异常处理像是与程序正常执行路径并行的、不会影响正常的代码,只在错误发生时执行另外一条路径。
  3. 异常处理提供了一种从错误状态恢复的途径。
  4. Java内置了异常处理,并强制使用,唯一可接受的错误报告方式,提供有保障的一致性。

1.12并发编程

计算机编程中有一个概念,就是在同一时刻处理多个任务的思想。(程序停下现在的工作,转而处理其他问题,在返回主进程。)有许多方法可以实现。一开始程序员用所掌握的机器底层的知识来编写中断服务程序,主进程挂起通过硬件中断来触发。这样可以解决问题但是难度太大,而且不能移植,转移程序时费时费力。

所以将问题分为多个可以独立的部分。提高任务的响应能力。线程是一种为单一处理器分配执行时间的手段。在程序中,彼此独立运行的部分成为线程。如果操作系统支持多处理器,那么每个任务都可以被指派给不同的处理器,并且它们是在真正的并行执行(并发)。

但是有一个隐患——共享资源。如果多个并行任务都要访问同一项资源,那么就会出问题。
Java的并发是内置在语言中的。

1.13 Java与Internet

1.13.1 Web是什么?

  1. 客户/服务器计算技术
    核心思想:系统具有一个中央信息存储池,用来处理某种数据,它通常存在于数据库中,根据需要分发给机器集群或某些人员。… …
    分发信息至关重要。
  2. web就是一台巨型服务器
    如何在某一时刻连接到一台服务器上,并与之交互?
    最初只有一个单向过程:你对某个服务器产生请求,然后它返回给你一个文件。

1.13.2 客户端编程

Web的最初设计者并没有预见到网络带宽被人们开发的各种应用迅速耗尽。于是就出来了客户端编程。这意味着Web浏览器能用来执行任何它可以完成的工作,使得返回给用户的结果更加迅捷,而且是你的网站更加具有交互性。

  1. 插件:程序员可以下载一段代码,并插入到浏览器中适当的位置,以此来为浏览器添加新功能。
  2. 脚本语言:通过某种脚本语言,你可以将客户端程序的源代码直接嵌入到HTML页面中。在HTML页面被显示时自动激活。缺点:代码会暴露给任何人去浏览,但问题不大。
  3. Java:通过applet以及使用Java Web Start来进行客户端编程。当applet被激活时,他便开始执行下一个程序。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值