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在线状态,可以一边聊天一边查看好友的状态。对这些问题,只能使用多线程来解决。

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

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

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

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

    2.1  创建新的数据类型:类 通过第一章掌握了面向对象的理论后,我们知道每个对象必定属于一个类型,那么Java如何创建新的数据类型?如下程序所示: class Circle { // 属性 // 方 ...

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

    4.1  return 关键字return有两方面的用途:一方面指定一个方法结束时返回一个值:一方面强行在return位置结束整个方法,如下所示: char test(int score) { if ...

  4. Java编程思想学习笔记——一切都是对象

    前言 Java是基于C++的,但Java是一种更加纯粹的面向对象程序设计语言. C++和Java都是混合/杂合型语言.杂合型语言允许多种编程风格. 用引用操纵对象 每种编程语言都有自己操纵内存中元素的 ...

  5. JAVA编程思想读书笔记(四)--对象的克隆

    接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...

  6. Java编程思想 学习笔记1

    一.对象导论 1.抽象过程 Alan Kay曾经总结了第一个成功的面向对象语言.同时也是Java所基于的语言之一的Smalltalk的五个基本特性,这些特性表现了纯粹的面向对象程序设计方式 1)万物皆 ...

  7. Java编程思想学习(五)----第5章:初始化与清理

    随着计算机革命的发展,“不安全”的编程方式已逐渐成为编程代价高昂的主因之一. C++引入了构造嚣(constructor)的概念,这是一个在创建对象时被自动调用的特殊方法.Java中也采用了构造器,并 ...

  8. Java编程思想 学习笔记5

    五.初始化与清理 1.用构造器确保初始化  在Java中,通过提供构造器,类的设计者可确保每个对象都会得到初始化.创建对象时,如果其类具有构造器,Java就会在用户有能力操作对象之前自动调用相应的构造 ...

  9. Java编程思想学习笔记_1(Java内存和垃圾回收)

    1.Java中对象的存储数据的地方: 共有五个不同的地方可以存储数据. 1)寄存器.最快,因为位于处理器的内部,寄存器按需求分配,不能直接控制. 2)堆栈.位于通用RAM,通过堆栈指针可以从处理器那里 ...

随机推荐

  1. c 语言的位运算符复习

    转载和修正,原文连接:http://www.cnblogs.com/911/archive/2008/05/20/1203477.html 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进 ...

  2. hibernate笔记--单向一对多映射方法

    上一篇讲的是单向多对一的表关系,与单向一对多的关系正好相反,如下图所示关系: ,可以看出年级表和学生表是一对多的关系,一条年级信息对应多条学生信息,在hibernate中成为单向的一对多的映射关系,应 ...

  3. hibernate笔记--组件映射方法

    假设我们需要保存学生student的信息,student中有一个address属性,我们知道像这种信息其值可能会有多个,就像一个人会有两个以上的手机号,这种情况在hibernate中应该这样配置: 新 ...

  4. HTTP在.NET中的一些应用和解析

    谈到HTTP协议(超文本传输协议),HTTP协议是一个基于请求与响应模式的.无状态的.应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在 ...

  5. Linux中读写权限

    learn the auth of Linux.   Generally, r-x w: write , modify and delete  -2 r: read   -4 x: execute   ...

  6. CloudNotes:一个云端个人笔记系统

    很长时间没有更新博客了,一直在忙着工作和生活琐事,虽然偶尔也有闲暇之时,但短短的几个小时空闲又未必能够静下心来.最近一个多月突发奇想,将自己在近一年前做的一个自己用的云端个人笔记系统重构美化了一下,增 ...

  7. JavaScript中的匿名函数及函数的闭包

    1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没有函数名的函数. 1.1 函数的定义,首先简单介绍一下函数的定义,大致可分为三种方式 第一种: ...

  8. 网页中的<th></th>是什么意思

    th定义表格内的表头单元格. html 表单中有两种类型的单元格: 1:表头单元格 - 包含表头信息(由 th 元素创建) 2:标准单元格 - 包含数据(由 td 元素创建) 注:th 元素内部的文本 ...

  9. Java--对象池化技术 org.apache.commons.pool2.ObjectPool

    org.apache.commons.pool2.ObjectPool提供了对象池,开发的小伙伴们可以直接使用来构建一个对象池 使用该对象池具有两个简单的步骤: 1.创建对象工厂,org.apache ...

  10. C标准头文件<stdlib.h>

    是个大杂烩,里面声明了从动态内存分配到常用算法等各种函数和宏 #数据类型 **size_t** **wchar_t** **div_t**是一个结构体类型,也是div()返回的类型 **ldiv_t* ...