思想才是一切的起点——岛屿心情《寻找》
Java核心技术Ⅰ
第四章 对象与类
4.1 面向对象程序设计概述
传统的结构化程序设计通过设计一系列的过程(即算法)来求解问题。一旦确定了这些过程, 就要开始考虑存储数据的方式。这就是 Pascal 语言的设计者 Niklaus Wirth 将其著作命名为《算法 + 数据结构 = 程序》的原因。需要注意的是,在 Wirth 命名的书名中, 算法是第一位的,数据结构是第二位的。而 OOP 却调换了这个次序, 将数据放在第 •位,然后再考虑操作数
据的算法。
4.1.1 类
由类构造(construct) 对象的过程称为创建类的实例 (instance ).
封装( encapsulation , 有时称为数据隐藏) 是与对象有关的一个重要概念。从形式上看,封装不过是将数据和行为组合在一个包中, 并对对象的使用者隐藏了数据的实现方式。对象中的数据称为实例域( instance field ), 操纵数据的过程称为方法( method 。) 实现封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域。程序仅通过对象的方法与对象数据进行交互。
4.1.2 对象
- 对象的行为(behavior)—可以对对象施加哪些操作,或可以对对象施加哪些方法?
- 对象的状态(state )—当施加那些方法时,对象如何响应?
- 对象标识(identity )—如何辨别具有相同行为与状态的不同对象?
对象的这些关键特性在彼此之间相互影响着。例如, 对象的状态影响它的行为。
4.1.3 识别类
设计类的方法:首先从设计类开始,然后再往每个类中添加方法。
4.1.4 类之间的关系
- 依赖(“ uses-a”)
- 聚合(“ has-a”)
- 继承(“ is-a”)
依赖:依赖( dependence ), 即“ uses-a” 关系, 如果一个类的方法操纵另一个类的对象,我们就说一个类依赖于另一个类。
应该尽可能地将相互依赖的类减至最少。用软件工程的术语来说,就是
让类之间的耦合度最小。
聚合:聚合关系意味着类 A 的对象包含类 B 的对象。
继承:下一章着重介绍,一个类包含另外一个类里面的所有,例如Java中的所有类都是继承于超类Object
UML符号
4.2 使用预定义类
Java中提前定义好的类,前面几章中使用到的Math类。Math 类只封装了功能,它不需要也不必隐藏数据。由于没有数据,因此也不必担心生成对象以及初始化实例域。
4.2.1 对象与对象变量
在 Java 程序设计语言中, 使用构造器(constructor ) 构造新实例。
一定要认识到: 一个对象变量并没有实际包含一个对象,而仅仅引用一个对象。new 操作符的返回值也是一个引用。
Date deadline = new Date();
表达式 new Date() 构造了一个 Date 类型的对象, 并且它的值是对新创建对象的引用。
- 局部变量不会自动地初始化为 null,而必须通过调用 new 或将它们设置为 null 进行初始化。
- 所有的 Java 对象都存储在堆中。 当一个对象包含另一个对象变量时, 这个变量依然包含着指向另一个堆对象的指针。
- 在 Java中,必须使用 clone 方法获得对象的完整拷贝
4.2.2Java类库中的LocalDate类
类库设计者决定将保存时间与给时间点命名分开。所以标准 Java 类库分别包含了两个类:一个是用来表示时间点的 Date 类;另一个是用来表示大家熟悉的日历表示法的 LocalDate 类。
LocalDate使用静态工厂方法 (factory method) 代表你调用构造器。
实际上,Date 类也有 getDay、getMonth 以及 getYear 等方法, 然而并不推荐使用这些方法。 当类库设计者意识到某个方法不应该存在时, 就把它标记为不鼓励使用。
4.2.3 更改器方法与访问器方法
更改器方法:某个对象调用方法时对此对象进行修改
访问器方法:某个对象调用方法时对此对象不进行修改,重新生成一个对象,返回这个对象的引用。
4.3 用户自定义类
4.3.1 User类
public class User {
//Field
public String username;
private String password;
protected Integer age;
//Constructor
public User(){
System.out.println("无参构造器!");
}
public User(Integer age){
System.out.println("有参构造器 age="+age);
}
private