面向对象程序设计概述
类
类是构建对象的模板或蓝图。由类构造(construct)对象的过程被称为创建类的实例(instance)。
封装是指不能让类中的方法直接访问其他类的实例字段。程序只能通过对象得到方法与对象数据进行交互。(这些实例字段就是这个对象的当前状态)
对象
对象的3个主要特征
- 对象的行为(behavior):有哪些方法。
- 对象的状态(state):有哪些实例属性。
- 对象的标识(identity):对象的标识(内存中的地址表示)。
类与类之间的关系
- 依赖(“uses-a”):A类中调用了B类或其实例。
- 聚合(“has-a”):A类中含有B类实例属性。
- 继承(“is-a”):A类继承自B类。
其UML表示如下:
final实例字段
注意final定义的实例字段必须在定义时、或者构造器对象时进行初始化。
对象构造
重载
一个方法的方法名和参数类型被称为方法的签名(signature)。即区分不同的方法是靠这两个点。
重载是指多个方法拥有相同的名字,不同的参数类型。在调用时传入特定的参数,由编译器选出对应的方法,如果不存在特定方法,则报错。这个过程被称为重载解析(overloading resolution)。
Note:
返回类型和修饰符都不是方法签名的一部分,因此不能存在两个名字相同、参数类型相同却有不同返回类型或不同修饰符的方法。(在Java语言层面不行,但是在虚拟机层面,是可以存在的,在类型擦除时经常会出现这样的情况)
数据字段初始化
- 在构造器中设置值。
- 在声明中赋值。
- 初始化块。
在一个类的声明中,可以包含任意多个代码块。只要构造这个类,这些块就会被执行。如:
1 | class Employee{ |
但是这种方式不是必须的,也不常见。通常会直接将初始化代码放置到构造器中。
类的导入
一个类可以始终所属包中的所有类,以及其他包中的公共类(public class)。
我们可以采用两种方式来访问另一个包中的公共类。
- 使用完全限定名。
- 使用import语句导入后直接使用。
Note:
只能使用星号(*)导入一个包,而不能使用
import java.*
或者import .*.*
导入以Java为前缀的所有包。当导入的两个包含有相同的方法名字,如果还是使用简写名,则会报错;此时需要使用全限定名。
静态导入
在import后加上static关键字则可以导入静态方法和静态字段,而不只是类。如:
1 | import static java.lang.System.*; |
还可以导入特定的方法
1 | import static java.lang.System.out |
类设计技巧
- 一定要保证数据的私有。
- 一定要对数据进行初始化。
- 不要在类中使用过多的基本类型。
- 不是所有的字段都需要单独的字段访问器和字段更改器。
- 分解有过多职责的类。
- 类名和方法名要能够体现它们的职责。优先使用不可变的类:即尽量使用那些调用方法后返回副本的类,而不是修改其内部属性的类。主要在于多线程同时试图更新一个对象,就会发生并发修改。其结果就是不可预料的。