欢迎跳转到本文原文链接 Backend_Notes
Java 是面向对象的语言,其中类 (class) 是构造对象的模板或者蓝图,由类构造(construct)的过程成为创建类的实例(instance)。
封装
封装(encapsulation)是与对象相关的一个重要概念。从形式上看,封装不过是将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式,对象中的数据成为实例域(instance field), 操纵数据的过程称为方法(method),对于每个特定的实例都有一组特定的实例域值,这个值的集合就是这个对象的当前状态(state)。无论何时,只要像对象发送一个消息,它的状态就可能发送改变。
实现封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域,程序仅仅通过对象的方法与对象数据进行交互。封装给对象赋予了“黑盒”的特征,这是提高重用性和可靠性的关键。
封装中使用了更改器(mutator)方法和访问器(accessor)方法,使用访问器(accessor)方法时需要注意:不要编写返回引用可变对象的方法。
todo: 补图
class Employee {
private Date hireDay;
public Data getHireDay() {
return hireDay; // Bad
return (Date) hireDay.clone(); // ok
}
}
对象
对象的三个主要特性:
- 对象的行为(behavior):可以对对象施加哪些操作或者方法:对象的行为是用可调用的方法定义的。
- 对象的状态(state):当施加方法时,对象如何响应:每个对象都保存着描述当前特征的信息,这就是对象 的状态,对象的状态可能会随着时间而发发生改变,但这种改变不会是自发的。对象状态的改变必须通过调用方法实现,如果不经过调用方法就改变状态,说明对象的封装性遭到了破坏。
- 对象的标识(identity):如何辨别具有相同行为和状态的对象:对象的状态不能完全标书一个对象,每个对象都有一个唯一的身份(identity),例如在订单系统中,任何两个订单都存在不同之处,及时所订购的货物相同也是如此。
类之间的关系
- 依赖(uses a):一个类的方法操纵另一个类的对象,如 Order 类依赖 Account 类,因为订单对象需要访问账户类查询信用状态、
- 聚合(has a):即类 A 的对象包含这类 B 的对象,如一个 order 对象包含这一些 item 对象。
- 继承(is a):用于标识特殊与一般关系,如 RushOrder 由 Order 类继承而来。
应该尽可能地将相互依赖的类减至最小。如果类 A 不知道 B 的存在,它就不会关系 B 的任何改变(这意味着 B 的改变不会导致 A 产生任何 bug),即应该让类的耦合度减小。
隐式参数与显示参数
类中的方法有两个参数,第一个参数称为隐式(implicit)参数,是出现在方法名前的类对象,第二个参数位于方法名后面括号的数值,这是一个显示(explicit)参数。可以看到显示参数是明显地列在方法声明中的,隐式参数没有出现在方法声明中。
a.test(1);
上述代码中,隐式参数为对象a, 显示参数为 1.
静态方法
静态方法是一种不能向对象实施操作的方法,如 Math.pow(x, a);
运行这行代码时,不能使用任何 Math 对象, 换句话说,没有隐式参数。可以认为静态方法是没有 this 参数的方法(在一个非静态的方法中,this 参数标识这个方法的隐式参数。)
下面两种情况可以使用静态方法:
- 一个方法不需要访问对象状态,其所需参数都是通过显示参数提供,如 Math.pow
- 一个方法秩序访问类的静态域
对象构造
重载
Java 中允许方法重载(overloading),要描述一个方法,需要指出方法名和参数类型,这叫方法签名(signature),需要注意,返回类型不是方法签名的一部分,因此不能有两个方法名相同,参数类型也相同却返回值类型不同的方法。
初始化
构造对象时初始化数据域有多种途径,所以列出构造过程的所有路径可能相当混乱,下面列出调用构造器的具体处理步骤:
- 所有数据域被初始化为默认值(0、false或null)
- 按照在类声明中出现的次序,依次执行所有域初始化语句和初始化块。
- 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体。
- 执行这个构造器主体。
访问权限
访问范围 | private | friendly(默认) | protected | public |
---|---|---|---|---|
同一个类 | 可访问 | 可访问 | 可访问 | 可访问 |
同一包其他类 | 不可访问 | 可访问 | 可访问 | 可访问 |
不同包子类 | 不可访问 | 不可访问 | 可访问 | 可访问 |
不同包非子类 | 不可访问 | 不可访问 | 不可访问 | 可访问 |
类的设计技巧
-
一定要保证数据私有
-
一定要对数据初始化
-
不要在类中使用过多的基本类型
-
不是所以的域都需要独立的域访问器和域更改器
-
将职责过多的类进行分解
-
类名和方法名要体现它们的职责
-
优先使用不可变的类