[Java编程思想-学习笔记]第1章 对象导论

1.1  抽象过程

Java是一门面向对象的语言,它的一个优点在于只针对待解问题抽象,而不用为具体的计算机结构而烦心,这使得Java有完美的移植性,也即Java的口号"Write Once, Run Anywhere"。

所谓的抽象过程,可以理解为对待解问题建模。比如待解问题是一个人,那么我们可以对人进行建模,它的类型是人,有属性姓名、性别、年龄,还有行为吃饭、走路。Java能直接完全据此建模编码,而无需考虑具体的计算机结构。所以当我们阅读Java程序时,正如书上说的"当你在阅读描述解决方案的代码的同时,也是在阅读问题的表述"。

1.2  对象的属性

正如我们所观察到的,人有属性姓名和年龄,圆有属性半径,三角形有属性边长和角度,每个对象都有一定的属性,也可以称属性是对象的成员。

1.3  每个对象都提供服务

每个对象都提供服务也是面向对象的一个重要的思想。

就像在人类世界里,造房子是为了住宿,造车子是为了出行,造学校是为了教育,造医院是为了医治。同样的,在Java中造对象当然是为了给用户使用。如果所造的对象没有一点用处,不能提供任何有用的服务,那简直成了垃圾对象。

既然每个对象都能提供服务,就意味着对象能做一些事,有一些公共方法可以被其他对象使用,这些公共方法也称为接口。

1.4  每个对象都有一个接口

面向对象有一个最重要的思想——物以类聚,各从其类。大千世界,无论何物,它都被视为一个实例化的对象,并且任何一个实例化的对象必定是按照一个模板创建出来的,其中此模板就是类。读过生物的应该都了解任何生物都可以根据"界、门、纲、目、科、属、种"进行分类,如果是非生物的,比如病毒、石头、沙子等,可当我们叫出它们的名字时,我们也找到了其所属的类。

科普一下接口的定义:简单来说,接口指的是“我能做什么”。(不妨打开JAVA的API,看看java.lang包,里面的接口如AppendableCloneableRunnable,后缀都是-able,这样的命名也体现了接口的含义)

问题来了,为什么要用接口?为什么每个对象都有一个接口?我们不妨看看电视机这个实例化的对象,我们按打开按钮时,它就收到"打开"的请求,然后内部就做了一些工作,最后屏幕就亮了,我们按下一个频道时,它就收到"下一个频道"的请求,然后内部就做了一些工作,最后显示下一个频道。其实每个对象都应有相同的工作机制,比如人吃饭,人吃一口饭,内部也就收到"吃"的请求,然后就是一系列的消化的工作,最后会化作每个细胞工作需要的能量。我们对这种工作机制抽象,因而有了接口和实现的概念。接口,就像暴露在电视机外面的按钮一样,有打开,上/下一个频道,音量+/-等功能按钮;实现,就像隐藏在电视机里面复杂的内部工作一样,它最好是隐藏起来的。之所以说每个对象都有一个接口,就是避免把类设计成黑盒子,如果电视机一个接口也没有,那么我们即使用遥控器也没能操作它,这样的电视机有什么用处?因此这就告诫每个程序员,设计类的同时必须至少定义一个公共方法。

1.5  被隐藏的具体实现

为什么要把具体实现隐藏起来?除了 1.4 节所述原因,还有另一个重要的原因。要知道这编程世界有两种程序员,一者曰类创建者(那些创建新数据类型的程序员),二者曰客户端程序员(那些在其应用中使用数据类型的类消费者)。最普遍的,假设称Java类库的创建者为A1(即类创建者),称我们这些使用Java类库的程序员为A2(即客户端程序员)。A1与A2形成一种关系,A1负责构建类,而A2使用A1提供的类来做开发。假设类创建者开发了一个计算组合数的类Combination,数学上组合数的公式为C(n,m)=m!/n!(m-n)!,我们可以定义两个方法,一个是计算阶乘,另一个是计算组合数,我们不希望计算阶乘的方法成为接口暴露出去,因为一旦暴露了,客户端程序员就可以随意设置参数,修改内部实现,因此应当把这类具体实现隐藏起来,这样才能避免被毁坏,减少程序的bug,此外,这样做对客户端程序员而言也是一种服务,因为这样他们就知道哪些方法是可用的,哪些方法是不可用的,还有一个原因是,当我需要修改隐藏的实现时,不会影响到客户端程序员,比如我原来是使用循环来实现阶乘的计算,但后来我发现用递归更加好,我这么一改,甚至连方法名都改了,但是这个类的接口依然没变,所以没影响到客户端程序员。

其实不仅要隐藏具体实现,还应当隐藏对象的属性。这些属性和具体实现的隐藏在面向对象中被称为封装。封装的意义在于保护了,比如人,他有属性年龄,我们都知道年龄必须是非负数的,如果没有封装起来,一些调皮的程序员就可以随意篡改了,比如改成 -1 岁,年龄哪能是负数?所以为了防止篡改,保护对象的属性,就引入了封装。

1.6  复用具体实现

复用具体实现是Java的一大特色了。这里涉及了类之间的关系:聚合、组合、继承、关联、依赖。

简单来讲,聚合就是拥有关系,但是两者生命周期不一致,比如人拥有一台电脑就是聚合关系,其中电脑的寿命到了,但人的寿命还没到,人的寿命到了,但电脑的寿命还没到;

组合也是拥有关系,更是一种强聚合关系,两者的生命周期是一致的。比如人和自己的大脑,两者谁也不能离开谁;

继承不用多说了,比如苹果继承自水果,苹果是水果;
关联也是拥有关系,不同的是,关联是一对多的关系,比如一个订单只能有一个客户,而一个客户拥有多个订单;

依赖就是使用关系,比如一个人要过河,他就需要使用一下船只,在代码里体现在一个类的方法定义了被依赖类的局部变量,或者被依赖类作为此类方法的参数。

1.7  继承

继承是复用代码的一种方式,它是指在现有的一个类的基础上创建一个新的类,被继承的类称为基类(或父类、超类),继承出的类成为导出类(或子类、次类)。

继承有三种情形,1.导出类什么都没做,因此导出类与基类完全一样;2.导出类覆盖(修改)了基类的方法,即导出类纯替代了基类;3.导出类添加了新的方法,还可能覆盖了基类的方法,此时导出类扩展了基类,实际上我们在继承时往往都是扩展基类。

在继承上Java与C++最大的不同就是单根继承了,每个类都只能继承自一个类,并且,Java中所有的类都直接或间接地继承自根类Object,如下图所示

1.8  伴随多态的可互换对象

如 1.7 节所示,我们可以说直角三角形是一个三角形,等边三角形是一个三角形,但三角形不一定是直角三角形或等边三角形。假设我们已经设计了三角形的继承体系,这时我们再设计一个操作三角形的类,类中有一个方法用来填充三角形,但已知有三种三角形,即直角三角形、等腰三角形以及等边三角形,难道要分别为这三种三角形重载三种填充方法吗?不必,多态使得只要在参数上接受三角形这种泛化的类型即可,也就是说,无论是哪种三角形,在多态上都视为三角形,因此能被方法的参数所接受,故也都能被填充。比如下面的程序:

// 不使用多态
void fill(直角 e) { print("填充直角三角形"); }
void fill(等腰 e) { print("填充等腰三角形"); }
void fill(等边 e) { print("填充等边三角形"); }
// 使用多态
void fill(三角形 e) { print("填充" + e); }

可见,因多态机制,代码更加简洁。

到此,补充一句面试爱问的问题:封装、继承和多态是面向对象的三个特征。

1.9  单根继承结构

如 1.7 节所示,Java中所有的类最终都继承自单一的基类,就是Object。这样的单根继承结构有三个优点:

  1. 所有对象都具有一个共用接口,这样它们归根到底都是相同的基本类型,在设计时还可以利用适配器模式解决接口不兼容问题;
  2. 保证所有对象都具备某些功能,比如都有toString( )equal( )方法;
  3. 使垃圾回收器的实现变得更加容易,因为能保证每个对象具有其类型信息。

1.10  容器

我们都知道在声明数组时必须要指定其大小,而一指定大小就再也不能改了,那问题来了,如果数组的大小仍然不够那怎么办?也只能重新再定义一个数组了,这样子就很不方便了。为解决这个问题Java提供了容器,容器能根据自己所需的元素个数动态地调整容器的大小。容器有SetMapList以及栈、队列、树等,其中面试最爱问的就是ArrayList了。

1.11  对象的创建和生命周期

在Java中,创建对象只要使用new关键字即可,然后对象就被创建在堆中,如果对象是创建在堆栈上,编译器就能确定它的生命周期,还可以销毁它,但对象是存在于堆中,编译器就无法确定对象的存活时间了。为了销毁对象,释放内存,Java提供了垃圾回收机制,程序员就不再需要手动销毁对象了,这对程序的编写的确是方便了许多。

当然Java这样做也是有弊端的,因为对象是存在于堆的,因此对对象的创建和操作会慢一些,此外把销毁对象的工作交给垃圾回收器,这样子有点不放心,如果程序退出了,但垃圾回收器还没有销毁对象呢,因此Java程序占用内存高就闻名世界了。

1.12  异常处理:处理错误

举个例子,我们设计一个简单除法的方法divide

int divide(int x, int y) { return x / y; }

这时如果对 y 赋值为0,程序就运行异常,然后二话不说直接退出,很明显程序体验太差,其实这情况还不算太差,如果是为银行、军事、航空设计程序,但没有处理好异常,那样子该有多危险。所以为了确保程序的健壮性,必须要能处理好异常。

1.13  并发编程

许多程序设计问题都要求,程序能够停下正在做的工作,转而解决其他问题。有的程序还要求能够同时做多件事情。比如下载,我们希望同时下载多个资源,支持断点续传,可以暂停下载;比如QQ在线状态,可以一边聊天一边查看好友的状态。对这些问题,只能使用多线程来解决。

时间: 2024-08-02 11:01:24

[Java编程思想-学习笔记]第1章 对象导论的相关文章

[Java编程思想-学习笔记]第3章 操作符

3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("Hello, world"); 我们都会感觉太冗长了,能不能简单一些呢?静态导入可以省略掉System,就像这样 import static java.lang.System.*; public class Hello { public static void main(String[] args) {

[Java编程思想-学习笔记]第2章 一切都是对象

2.1  创建新的数据类型:类 通过第一章掌握了面向对象的理论后,我们知道每个对象必定属于一个类型,那么Java如何创建新的数据类型?如下程序所示: class Circle { // 属性 // 方法 } 如上所示,使用关键字class定义了类Circle,用花括号{ }将整个类包括起来.当然,这个类还不能做任何事,它还需要定义一些属性和方法. 2.2  属性和方法 面向对象的一个特性就是将数据和方法结合起来.比如对一个圆抽象,可见圆有它的属性半径,它还有方法,如告诉我们它的周长和面积.不光是

[Java编程思想-学习笔记]第4章 控制执行流程

4.1  return 关键字return有两方面的用途:一方面指定一个方法结束时返回一个值:一方面强行在return位置结束整个方法,如下所示: 1 char test(int score) { 2 if (score >= 90) 3 return 'A'; 4 if (score >= 80) 5 return 'B'; 6 if (score >= 70) 7 return 'C'; 8 if (score >= 60) 9 return 'D'; 10 else //if

Java编程思想学习笔记十一:持有对象

一.基本概念 1.Collecction:一个独立元素的序列,这些元素服从一条或多条规则.list必须按照插入的顺序保存元素:set不能有重复的元素:Queue按照排队规则来确定对象产生的顺序 2.Map:映射表,一组由成对的键值对对象,允许使用键来查找值 1 package holding; 2 import java.util.*; 3 4 public class SimpleCollection { 5 public static void main(String[] args){ 6

【Java编程思想--学习笔记(一)】访问控制-包

Java编程思想–学习笔记(一) 访问控制(或隐藏具体实现)与"最初的实现并不恰当"有关. 1.包:库单元 我们之所以要导入包,就是要提供一个管理名字的空间机制. 每个java文件只能有一个public类.其他私有类为主public·类提供支持. 1.1 代码组织 与编译型语言不同,java可运行程序是一组可以打包并压缩成java文档文件(JAR,使用Java的jar文档生成器)的.class文件. 使用package和import关键字,使得不会出现名称冲突问题. 注意:java包的

JAVA编程思想学习笔记——第一章 对象导论

搞了一年多java,野路子出身,发现java基础这块还是相当的薄弱!故决定学习<Java编程思想>这本书.在此把学习的知识点记录下! 面向对象的五大特性 1.万物皆为对象 2.程序是对象的集合,它们通过发送消息来告诉彼此所要做的 3.每个对象都由自己的由其它对象所构成的存储 4.每个对象都拥有其类型 5.某一特定类型的所有对象都可以接收同样的信息  单根继承结构 所有的类都继承自单一的基类,Object.在单根集成结构中的所有对象都具有一个公用接口,所以他们归根到底都是相同的基本类型.单根集成

【java编程思想--学习笔记(四)】对象导论

写这篇博客的前言: 长话短说,我希望通过阅读<java编程思想>来使我的代码 简洁可用 . 目的的层次不同,首先具体的目标是,了解Java的特性和巩固Java的基础. 更抽象的目的如下: 1.期待以巩固基础的方式,使代码优美,简洁,高效. 2.使自己写的模块能够开放适度,好用. 3.形成一种对代码是否优美的审美观. 于是<Java编程思想>第一章 对象导论 由此开始. 1.1 抽象过程 java 相对于命令式语言的优势在于只针对于待解问题建模.后者所做的主要抽象要求所做问题基于计算

Java编程思想 学习笔记1

一.对象导论 1.抽象过程 Alan Kay曾经总结了第一个成功的面向对象语言.同时也是Java所基于的语言之一的Smalltalk的五个基本特性,这些特性表现了纯粹的面向对象程序设计方式 1)万物皆对象. 2)程序是对象的集合,它们通过发送消息来告知彼此所要做的.要想请求一个对象,就必须对该对象发送一条消息.更具体的说,可以把消息想象为对某个特定对象的方法的调用请求. 3)每个对象都有自己的由其他对象所构成的存储.换句话说,可以通过创建包含现有对象的包的方式来创建新类型的对象. 4)每个对象都

Java编程思想学习笔记_1

1.Java中对象的存储数据的地方: 共有五个不同的地方可以存储数据. 1)寄存器.最快,因为位于处理器的内部,寄存器按需求分配,不能直接控制. 2)堆栈.位于通用RAM,通过堆栈指针可以从处理器那里获得直接支持.堆栈指针向下移动,分配新的内存,向上移动,则释放那些内存.Java系统必须知道存储在堆栈内的所有项目的确切的生命周期. 3)堆.编译器不需要知道存储的数据在堆里活多长时间. 4)常量存储.通常直接放在代码内部. 5)非RAM存储,如果数据完全存活与程序之外,那么它可以不受程序的任何控制