你能看到这句话,说明你不错哦
thinking in java 读书笔记
作者:淮左白衣
写于 2018年4月10日20:36:39
目录
toString()方法
在我们使用 “+” 、System.out.println(s)
的时候,当编译器需要一个字符串的时候,而我们传给它一个对象引用的时候,编译器会自己去调用 toString()方法;
我们可以看下System.out.println(s)
的源码
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
我们看到当我们传一个对象进去,调用了 String.valueOf()
方法,并不是我们说的 toString()
方法,我们不妨再跟进去,看下 String.valueOf()
的源码 ;
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
这下我们看到了,我们朝思暮想的 obj.toString()
;
关于父类与子类的故事
在java中,我们都知道 new 子类的时候,子类构造器的第一句代码隐式的调用了父类的构造器 ;那么是否意味着,在创建子类对象的时候,也创建了父类对象呢?假如创建的父类对象,那么父类对象又在哪里呢?
答案是肯定的!当我们创建一个子类对象的时候,该子类对象中包含了一个父类对象 ;这个父类对象,跟我们直接 new 出来的父类对象是一样的!
具体内容,可参考《Thinking in java》P129 ;
复用代码的中庸之道 — — 代理
说真的,我今天上午(2018年4月10日)看到代理的时候,并没有理解 代理 和 组合 有什么区别 ; 我感觉 代理 是 组合 的阉割版 ;代理 给类的使用者,一种半残品,只暴露了想要给你使用的部分(这也叫控制力强);而组合,则是给类的使用者,暴露了表面上的所有(类的public部分)!这个暴露,和继承不一样,继承是把底裤都给暴露了 ;
举个例子,说明下代理的用法
先看图:
现在我们的 民用飞机 想要装一个 飞行控制系统 ,但是,飞行控制系统上面,除了控制飞行外,还有一个发射导弹的系统;这是万万不能给民航飞机用的 ;
现在问题就是我们的民航飞机想要复用飞行控制系统,但是需要一点点的约束 ;如何复用?继承我们不用考虑了,它俩根本就不是 ‘is - a ’ 关系 ;
因此只能在组合 和 代理 里面选一样 ,组合 VS 代理
先说 组合,我们在民用飞机里面放一个飞行控制系统,我们虽然,可以不使用发射导弹的功能,但是我们保不准会有失误的时候,让民航飞机发射了一颗导弹出来。。。。这是要不得的!
你可能会想到,我们有没有一种办法,对飞行控制系统进行控制,或者说削弱飞行控制系统的功能呢?那就选择 代理 了,我们在飞行控制系统上层,再封装一个系统出来,这个系统只对外提供飞行功能,把发射导弹的功能阉割掉!然后,把封装出来的系统,装进民航飞机里面,这样民航飞机无论如何,也将发射不出导弹来了 !
总结:如果需要的功能类,刚好满足我们的需要,就直接组合;如果,功能类里面有些东西,不是我们需要的,就设计一个代理类,将我们需要的功能封装出来;
代理的代码体现
// 飞行控制系统
class FlyAndMissile {
// 飞行功能
public void fly() {
}
// 发导弹功能
public void missile() {
}
}
// 将飞行功能,封装到一个代理类里面
class Fly {
FlyAndMissile flyAndMissile = new FlyAndMissile();
// 将飞行功能,提取出来
public void fly() {
flyAndMissile.fly();
}
}
// 民航飞机
class Plane {
// 将代理类 放进来
Fly fly = new Fly() ;
// 飞行,fly打死也不会提供发射导弹的功能
public void fly() {
fly.fly();
}
}
我们看出,代理给了我们更强的控制能力 ;
备注
我有个疑问?既然有代理,为何还需要组合?