你不可能踏进同一条河两次

Q:你会Java?
A:是。

Q:请用Java描述一个工人,它有姓名和工龄(可以理解成这项工作做了多少年)
A:简单:

class Worker {
private String name;
private int years;

// Getters and setters ...
}


Q:嗯。很好。继续:程序员是是一种工人,他熟悉一种语言。
A:也简单。看好:

class Programmer extends Worker {
private String language;
}


Q:相当不错!接下来,经理是一种工人,它管理多个工人。
A:看着:

class Manager extends Worker {
private List<Worker> workers;
}


Q:完美!现在,有一位叫张三的程序员,还有一名叫李四的经理,管理张三。
A:

// in some method...
Programmer zhangSan = new Programmer();
zhangSan.setName("张三");
Manager liSi = new Manager();
liSi.addWorker(zhangSan);


Q:现在,张三不当程序员了,也当了经理,但仍然是李四的下属。
A:应该这样吧:

// patch some codes
-Programmer zhangSan = new Programmer();
+Worker zhangSan = new Programmer();
// new codes
zhangSan = new Manager();


Q:哎哎,等一下。你创造了一个新的对象。我是说张三变成经理了。
A:是啊。张三变了,就不是原来那个张三了。

Q:岂有此理,黄河水还每天流呢,难道说明天就不是原来那个黄河了吗?
A:记得赫拉克里特是这么说的。而且,String a="foo"; a="bar";a不是也变成新的对象了吗?

Q:那么,liSi那里保留的zhangSan的引用,还是原来的?
A:这……还是原来的,没有更新。


Q:插一句,张三改名叫张无忌了,怎么实现?
A:

zhangSan.setName("张无忌");


Q:哎?改个名字,倒还是原来那个对象阿。
A:是。只要不改职业就行。
Q:为什么改名字行,改职业就不行?
A:谁让Java是“静态类型语言”呢?每个对象都有一个在运行时无法改变的“类型“。我知道的是这样,是不是真的不能改,我才疏学浅,就不知道了。


Q:算了。继续。王五是一个工人,干程序员干了10年,经理干了5年,现在双重职位。
A:这可能吗?
Q:需求如此。
A:……好像不行。我用C++试试

class ProgrammerAndManager : public Programmer, public Manager {
private:
// no new attribute
};

ProgrammerAndManager *wangWu = new ProgrammerAndManager();


Q:嗯。wangWu对象里面,years这个成员变量保留了几份?
A:两份。一份从Programmer继承,另一份从Manager继承。
Q:那么,name有几份?
A:也是两份。
Q:这么说,王五干两个工作还起不同的名字?
A:。。。也许吧。或者……这样:

class Programmer : virtual public Worker {
// ...
};
class Manager : virtual public Worker {
// ...
};


Q:这下子,从两边继承的name就是共享的了。
A:正是
Q:那么,years呢?他做两个工作时间不一样长。
A:这……没办法了。

A:我试试重构一下

class Worker {
private String name;
private List<Job> job;
}

class Job {
private int years;
}

class Programmer extends Job {
private String language;
}

class Manager extends Job {
private List<Worker> workers;
}

// within some method
Worker zhangSan = new Worker();
zhangSan.addJob(new Programmer());

Worker liSi = new Worker();
liSi.addJob(new Manager());

Worker wangWu = new Worker();
wangWu.addJob(new Programmer(10));
wangWu.addJob(new Manager(5));


Q:看似不错。现在,让王五写一段程序,要签名的。
A:这样:
[code]
// Change this class:
class Job {
private Worker worker; // Associated worker
}
class Programmer extends Job {
private String language;
public writeProgram() {
System.out.println(this.getWorker().getName() +
"wrote a program in " +
this.getLanguage());
}
}

pubic static void main(String args) {
Programmer wangWuSProgrammerAspect = new Programmer("java",5);
Worker wangWu = new Worker();
wangWu.setName("王五");
wangWu.addJob(wangWuSProgrammerAspect);

wangWuSProgrammerAspect.writeProgram();
}
[/code]

Q:不错。不过,看上去不是wangWu本人在写程序。
A:嗯。倒像是wangWu体内的某种Programmer本能在代替他本人作出行为。
Q:那么,wangWu还算是会写程序的吗?
A:要不这样?
[code]
class Worker {
void writeProgram() {
throw new MethodNotImplementedException();
}
}
[/code]
Q:不好。360行的动作都写进来?
A:还是算了吧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值