当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

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

发表于: 2010-07-05   作者:cloverprince   来源:转载   浏览:
摘要: Q:你会Java? A:是。 Q:请用Java描述一个工人,它有姓名和工龄(可以理解成这项工作做了多少年) A:简单: class Worker { private String name; private int years; // Getters and setters ... } Q:嗯。很好。继续:程序员是是一种工人,他熟悉一种语言。
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:这样:
// 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();
  }


Q:不错。不过,看上去不是wangWu本人在写程序。
A:嗯。倒像是wangWu体内的某种Programmer本能在代替他本人作出行为。
Q:那么,wangWu还算是会写程序的吗?
A:要不这样?
class Worker {
  void writeProgram() {
    throw new MethodNotImplementedException();
  }
}

Q:不好。360行的动作都写进来?
A:还是算了吧。

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号