Q:你会Java?
A:是。
Q:请用Java描述一个工人,它有姓名和工龄(可以理解成这项工作做了多少年)
A:简单:
Q:嗯。很好。继续:程序员是是一种工人,他熟悉一种语言。
A:也简单。看好:
Q:相当不错!接下来,经理是一种工人,它管理多个工人。
A:看着:
Q:完美!现在,有一位叫张三的程序员,还有一名叫李四的经理,管理张三。
A:
Q:现在,张三不当程序员了,也当了经理,但仍然是李四的下属。
A:应该这样吧:
Q:哎哎,等一下。你创造了一个新的对象。我是说张三变成经理了。
A:是啊。张三变了,就不是原来那个张三了。
Q:岂有此理,黄河水还每天流呢,难道说明天就不是原来那个黄河了吗?
A:记得赫拉克里特是这么说的。而且,String a="foo"; a="bar";a不是也变成新的对象了吗?
Q:那么,liSi那里保留的zhangSan的引用,还是原来的?
A:这……还是原来的,没有更新。
Q:插一句,张三改名叫张无忌了,怎么实现?
A:
Q:哎?改个名字,倒还是原来那个对象阿。
A:是。只要不改职业就行。
Q:为什么改名字行,改职业就不行?
A:谁让Java是“静态类型语言”呢?每个对象都有一个在运行时无法改变的“类型“。我知道的是这样,是不是真的不能改,我才疏学浅,就不知道了。
Q:算了。继续。王五是一个工人,干程序员干了10年,经理干了5年,现在双重职位。
A:这可能吗?
Q:需求如此。
A:……好像不行。我用C++试试
Q:嗯。wangWu对象里面,years这个成员变量保留了几份?
A:两份。一份从Programmer继承,另一份从Manager继承。
Q:那么,name有几份?
A:也是两份。
Q:这么说,王五干两个工作还起不同的名字?
A:。。。也许吧。或者……这样:
Q:这下子,从两边继承的name就是共享的了。
A:正是
Q:那么,years呢?他做两个工作时间不一样长。
A:这……没办法了。
A:我试试重构一下
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:还是算了吧。
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:还是算了吧。