第2章
类和接口(Classes and Interfaces
)
1
最小化类和成员的可访问性(Minimize the accessibility of classes and interfaces
)
衡量一个模块好坏的一个重要标准就是该模块对其它模块隐藏内部数据和实现细节的程度。
经验规则就是尽可能的让类或成员的可访问度越低越好。
保护成员也是输出的API的一部分。需要保护成员的情况应该很少见。
拥有public static final的数据域总是错误的。
除了public static final域外,公共类不应该有公共域。
2
多使用不变性(Favor immutability
)
为了使一个类成为不变的,有如下五条规则:
1) 不要提供任何修改对象的方法。
2) 保证没有方法是可以被重载的。
3) 把所有的域变成final。
4) 把所有的域变成私有的。
5) 确保对任何可变部分的独占访问。
不变的对象简单,而且是线程安全的,可以被随意共享。
不变对象的缺点是你必须为美一个不同的值创建一个对象。
当不变对象的性能不能令人满意时,考虑提供一个可变的对象完成同样的功能,如String和StringBuffer。
即便一个类无法是不变的,也应该尽可能的限制其可变性。
3
优先使用组合而不是继承(Favor composition over inheritance
)
在包内使用继承是安全的。
不同于方法调用,继承破坏了封装性。
组合可以考虑使用Decorator模式。
4
设计和文档化继承或者禁止它(Design and document inheritance or else prohibit it
)
类必须准确的记录下重载每个方法的效果。
为了确保一个类可以被安全的继承,你应该描述相关的实现细节。
构造函数,clone,readObject方法不应该直接或间接的调用可被重载的方法。
设计成可被继承对该类附加很大的限制。
最好的办法是不允许继承,而采用组合。
要防止类自身的方法对可被重载的方法的调用。
5
优先使用接口而不是抽象类(Prefer interfaces to abstract classes
)
抽象类可以有部分的实现,而接口不可以。
由于Java是单继承的,这极大的限制了抽象类作为类型定义的使用。
已有的类可以很容易的实现新的接口。
接口是定义混入类(mixin)的理想方式。
接口使得可以构造非层次类型结构的框架。
接口使得可以很安全的增强功能。
可以把接口和抽象类的优点结合起来,对每个输出的nontrivial的接口提供概要实现。
抽象类的演进比接口要容易得多。
6
只使用接口来定义类型(Use interfaces only to define types
)
7
优先使用静态成员类而不是非静态的(Favor static member classes over nonstatic
)
每个非静态成员类的实例隐式的与包含它的类的实例关联。
如果你定义的成员类不需要访问包含它的类的实例,记得将其变为静态的。
匿名类用在只需要在代码的单个点上初始化的时候。较长的匿名类会损害程序的可读性。