Practicle Java笔记 实践59-68(完)
?
实践59
运用interfaces支持多重继承
实践60
没有任何办法能够阻止两个interfaces使用同名的常数和函数,为了避免可能的冲突,应当小心命名常数和函数。
例如例子中给出的 interface Golf和interface Bowling都有computeScore在实现时 为了加以区分 只能再额外创建一个MyGolf或MyBowling 之后让类实现MyGolf/MyBowling来区分开2者间的计算(在使用不同程序提供的接口时可能会出现这种情况)
实践61
如需提供部分实现(partial implementation),请使用抽象类(abstract classes),这些实现很可能对derived class是共通的
实践62
理解和区分interface,abstract class和concrete class之间的差异
interface内函数默认public,常量默认public static final
实践63
谨慎定义和实现不可变类(immutable classes)
如果你希望对象内容永远不被改动,请使用不可变对象(immutable object),这种对象自动拥有“多线程安全性”。
1 将class中所有的数据声明为private?
2 只提供取值函数,而不允许存在setter
3 声明class为final (放置被子类化 而子类复写getter或setter)
4 从获取器返回reference给可变对象时,先克隆可变的对象
5 将传递给构造函数的可变对象reference先克隆一份
6 在构造函数中设定class内含的所有数据
实践64
如果不实施克隆动作,你的对象不变性(immutability)就得不到保证。这是因为他处可能保留了这个immutable object 内的某个object 的reference,并对其进行了修改,从而冲破了不变性的[界限]。
考虑一个情况 final class内部有一个非final的对象 而在其中改变了该非final对象的内部属性 由于保存的是reference的关系 final class的object必然也被改变了(就是这种情况)
所以欲传递或接收可变对象(mutable objects)的object references时,请使用clone()。为了保证immutable objects,你必须在传入和回传它们时对它们施行clone()。
注意:Vector实现的clone是浅克隆,如果需要,必须自己实现深克隆版本,例如
?
class Base{private int val;Base{val=lookup();}public int lookup(){return 5;}public int value(){return val;}}class Derived extends Base{private int num=10;public int lookup(){return num;}}class Test{public static void main(String args[]){Derived d=new Derived();System.out.println(d.value());}}
这里打印的结果是0!
这与预期的结果10不符,原因在于lookup函数是在Derived对象建构期间由Base构造函数调用的,当进入Derived的lookup()时,其instance变量初始化行为还未被进行,因此使用了缺省值0。
?