Java编程思想(一)

前面我们在网站上面学过 java,但是学到的东西不够系统。这里通过对 Bruce Eckel《Thinking in Java》的学习,希望可以系统的掌握 java 的相关知识。在这本书之后,还需要学习 JVM 相关知识。才称得上对 java 有一定的理解。

这一系列的读书笔记结合自己的实际情况,参考 leonliu06 的文章,供自己日后学习、回顾之用。


第1章 对象导论

这一章主要介绍 面向对象程序设计(Object-oriented Programming,OOP)的概念和背景。是对整个 java 编程思想的高度概括。可以先看这一章,也可以先看后面章节,在对具体代码有了一定的应用后,再回过头来看这一章,相信会有更深的理解。

1.1 抽象过程

java 和 c++ 是面向对象的语言(可以简单理解为有 类 class 的语言),相比之下,c 就是面向过程的语言。
这里的类,就是抽象数据类(就好像 int 也是一个数据类,而3是该类的一个对象),对应就是抽象的过程。我们程序员要做的,就是如何做好这个抽象过程。

1.2 每个对象都有一个接口

所谓对象,就是一个类的实例。对象具有 状态(内部数据给出对象的状态)、行为(方法产生行为)和标识(每个对象在内存中有唯一的地址,区别于其他对象,是标识)。而类就是有相同特性(数据元素)和行为(功能)的对象集合。
这里给一个例子:

类型名称 Light
接口 on()、off() 、brighten()、dim()

接口确定了对某个对象可以发出的请求(可以看到这里所谓的接口,就是类中的成员函数)。

Light lt = new Light();
lt.on();

上面代码中,我们首先创建了一个 Light 对象:定义这个对象的引用(lt),然后调用 new 方法来创建一个该类型的新对象。为了向对象发送消息,需要声明对象的名称(这里是lt),并以原点连接一个消息请求。

可以说就是在类中的成员函数叫接口,在对象中的成员函数叫请求。

1.3 每个对象都提供服务

讲对象看做是其可以提供服务的集合,使得程序具有更好的可读性和可重写性。
比如对象1只提供A服务,对象2只提供B服务,对象3只提供C服务,三个一起,可以完成整个程序所需的功能。

1.4 被隐藏的具体实现(访问控制)

将程序员分为 类创建者客户端程序员(使用别人创建好的类库,比如你自己)。客户端程序员可以基于类创建者创建好的类 来做一些快速开发。但是作为创建者,不希望类内所有的内容都可以被访问,而需要隐藏一部分(通常是内部脆弱的部分),这样可以减少bug。
访问控制,就是做这件事的。这里有三个关键字:

  • public:谁都可以访问
  • private:类创建者和类内部 方法可以访问
  • protected :与private差别在于,继承类可以访问
    如果没有指定关键字,java 中默认访问权限为 **包package访问权限,即同一个包总可以访问。

1.5 复用具体实现

代码复用是对象程序语言的一个巨大优点。
这里所谓的复用,就是可以用之前的写好的类。有两种方法:组合、继承。
所谓组合就是创建一个新的类去调用已有类,新类就可以叫做一个组合。

public class People{
   // People 方法
}
class Student{
    People people = new People();
   // Student 方法
}

而继承,则是用 extends 关键字继承父类所有的方法。

public class People{
   // People 方法
}
class Student extends People{
  // 新写的Student 方法。
已经包含People 父类所有非private方法。
}

什么时候用哪个呢?其实很简单,如果 存在 “is-a”关系,(比如 Bee 是一个 Insect),即所有的Insect方法都需要,用继承。如果是 “has-a”关系(Bee 有一个 Insect的 move功能),就要用组合。
组合和继承的区别

1.6 继承

基本概念你已经清楚了,常见的做法是:把比较核心的概念写在基类中,继承类表示这些核心的各种实现方方式。
这里需要明白一个概念,基类和导出类具有相同的类型。比如圆形类继承自几何形类,二者其实都属于几何类。
如何让继承类和基类产生不同,这里给出了两种途径:添加新方法、方法重写(overriding)。第一种就加一个方法、第二种直接给出已有方法的重新定义(实现代码)。
这里在两种方法的选择上(是否需要增加新的方法),给出了 "is-a" & "is-like-a" 的关系,很直观。

1.7 伴随多态的可互换对象

面向对象的语言使用了 动态绑定(后期绑定)的概念。当向对象发送消息时,被调用的代码直到运行时才可以确定。
发送消息后,编译器只确保被调用方法的存在,并对调用参数和返回值类型检查(无法提供此类保证的语言叫 若类型语言),但是不知道将被执行的确切代码。
将导出类看做基类的过程叫做向上转型(upcasting)。

//  首先写一个方法,可以看到这个方法的参数是 Shape 对象
void doSomething(Shape shape){
    shpae.erase();
    shape.draw();
}
// 方法的具体实现.
// 这里写的参数是 circle对象,但是可以通过 upcasting,Circle对象可以被看做 Shape对象。
doSometihing(circle);
doSometihing(triangle);

1.8 单根继承结构

在 java(事实上包括 c++在内的所有OOJ语言)中,所有的类都继承自一个基类。 这个终极老鸡鸡叫做 Object。这样的单根继承结构有以下优点。

  • 所有对象都具有一个共用接口,所以,所有的对象归根结底都是相同的基本类型(upcasting思想)
  • 单根继承结构保证所有对象都具备某些功能(Object的功能)
  • 单根继承结构使得垃圾回收器的实现变得容易很多,而垃圾回收器正是 java 相对 C++ 的重要改进之一。由于所有对象都保证具有基类信息,因此 不会因为无法确定对象类型而陷入僵尸

1.9 容器

如果事先不知道解决一个问题需要多少个对象,就不知道需要创建多大的空间来存储对象(比如一个数组创建时,不知道里面的元素有多少个)。这里我们就要用到容器。
一个容器的对象,只需要扩充自己来容纳其中的东西,所以我们并不需要知道到底有多少个对象置于容器中。
java 中,提供了不同种类的容器,比如 List(用于存储序列)、Map(用来建立对象之间的关系)、Set(不含重复的对象,或者说元素)、以及队列、树、堆栈等很多组件。其中不同的容器提供了不同的接口和行为,并且不同容器对于某些操作具有不同的效率。

参数化类型

在 Java SE5之前,所有容器存储的对象都只具有Java中的通用类型:Object。 这里就有一个问题,不同对象存储时候 upcasting,但是具体用的的时候需要 donwcasting,这样就需要编写额外的代码来解决 downcasting 的问题。
如果我们一开始就指定了容器存储的类型,就是增加所谓的参数化类型(或者说叫泛型),用一对尖括号包含:

List test = new ArrayList();

1.10 对象的创建和生命期

这里先说一下简单的理解。后期看的更多应该会有更深的理解

java采用动态内存分配方式,创建一个对象时,使用 new 关键字构建此对象的动态实例,存储在 堆heap 中。
同时,java中 垃圾回收器被设计用来处理内存释放问题。在堆上创建的对象,编译器对其生命周期一无所知,而垃圾回收器可以自动发现对象何时不被使用,从而销毁对象,释放内存。

1.11 异常处理:处理错误

1.12 并发编程

把问题切分成多个可独立运行的部分(任务),每个独立部分叫做“线程”,整个叫“并发”。
并发编程的过程是:某个任务锁定某项资源,完成其任务,然后释放资源锁,使得其他任务可以访问这个资源。

你可能感兴趣的:(Java编程思想(一))