Wu Jun 2020-01-04 07:43:49
Categories: > > Tags:

1 类

类是构造对象的模板。

由类构造对象的过程称为创建类的实例。

一个源文件中,只能有一个公共类,类名必须与文件名相同。

1.1 类之间的关系

最常见的关系有:

  1. 依赖(uses-a):一个类的方法需要操纵另一个类的对象
  2. 聚合(has-a):类 A 的对象包含着类 B 的对象
  3. 继承(is-a):继承是一种用于表示特殊与一般的关系,父类更一般

应该尽可能地将相互依赖的类减至最少。

1.2 构造器

  1. 构造器和类名同名,参数不限,没有返回值。
  2. 构造器中的局部变量会覆盖同名实例域。
  3. 若未手动编写构造器,会默认提供一个无参构造器,设默认值。手动提供构造器后,不会自动提供无参构造器。
  4. 构造器不能被继承,因此不能被重写,但可以被重载。
  5. 父类与子类的构造函数调用次序:若子类构造器没有显式调用父类构造器,不管子类构造器有无参数,都默认调用父类无参构造器。

1.3 finalize 方法

可以为任何一个类添加 finalize 方法,将在垃圾回收器清除对象之前调用。不要依赖,不能保证被调用。

1.4 Object:所有类的超类

如果重新定义 equals 方法,就必须重新定义 hashCode 方法。eauals 与 hashCode 的定义必须一致:如果 x.eauals(y) 返回 true,那么 x.hashCode() 必须与 y.hashCode() 具有相同的值。

1)equals()方法
等价关系

两个对象具有等价关系,需要满足以下五个条件:

等价与相等
实现
2)hashCode()

hashCode() 返回哈希值,而 equals() 是用来判断两个对象是否等价。等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价,这是因为计算哈希值具有随机性,两个值不同的对象可能计算出相同的哈希值。

在覆盖 equals() 方法时应当总是覆盖 hashCode() 方法,保证等价的两个对象哈希值也相等。

HashSet 和 HashMap 等集合类使用了 hashCode() 方法来计算对象应该存储的位置,因此要将对象添加到这些集合类中,需要让对应的类实现 hashCode() 方法。

3)toString()

默认返回 ClassName@4554617c 这种形式,其中 @ 后面的数值为散列码的无符号十六进制表示。

4)clone()

clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。

clone() 方法并不是 Cloneable 接口的方法,Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() 方法,就会抛出 CloneNotSupportedException。

使用 clone() 方法来拷贝一个对象即复杂又有风险,它会抛出异常,并且还需要类型转换。Effective Java 书上讲到,最好不要去使用 clone(),可以使用拷贝构造函数或者拷贝工厂来拷贝一个对象。

1.5 枚举类

枚举类定义的是一个类,有着指定的几个实例。
比较两个枚举类型的值时,不需要调用 equals 方法,而直接使用"=="就可以了。

2 对象

2.1 创建对象

  1. 用 new 语句创建对象
  2. 运用反射
  3. 调用对象的 clone() 方法
  4. 运用反序列化手段,调用 java.io.ObjectInputStream 对象的 readObject() 方法

(1) 和 (2) 都会明确的显式的调用构造函数;(3) 是在内存上对已有对象的影印,所以不会调用构造函数;(4) 是从文件中还原类的对象,也不会调用构造函数。

2.2 对象克隆

有两种方式:

2.3 序列化

3 方法

3.1 方法签名

方法签名只有方法名参数,没有返回值。也就是说,不能有两个名字相同、参数也相同而返回值不同的方法。

3.2 隐式参数与显式参数

隐式参数是出现在方法名前的类对象(this),显式参数位于方法名后面的括号中。

使用 this 可以区分开隐式参数的类对象的实例域和局部变量

3.3 方法参数

Java 方法参数是值传递,不是引用传递。

方法在执行时,先定义了局部变量,这些局部变量指向,传入参数的指向。对局部变量重新指向时,完全不影响原本传入参数的那些指向。

3.4 参数变量可变的方法

Object… 参数类型与 Object[] 完全一样,省略号表明这个方法可以接收任意数量的的对象。