黑马程序员技术交流社区
标题:
在装饰模式遇到的一个问题
[打印本页]
作者:
创造命运
时间:
2014-4-16 10:28
标题:
在装饰模式遇到的一个问题
昨天学习了装饰者模式,看老师的视频时,觉得理解了。可是刚刚看 Java设计模式.chm 文里的装饰模式时,把我给弄糊涂了。
源代码如下:
//Component
interface Person {
void eat();
}
//ConcreteComponent
class Man implements Person {
public void eat() {
System.out.println("男人在吃");
}
}
//Decorator
abstract class Decorator implements Person {
protected Person person;
public void setPerson(Person person) {
this.person = person;
}
public void eat() {
person.eat();
}
}
//ConcreteDecorator
class ManDecoratorA extends Decorator {
public void eat() {
super.eat();
reEat();
System.out.println("ManDecoratorA类");
}
public void reEat() {
System.out.println("再吃一顿饭");
}
}
class ManDecoratorB extends Decorator {
public void eat() {
super.eat();
System.out.println("===============");
System.out.println("ManDecoratorB类");
}
}
//Test
public class Test {
public static void main(String[] args) {
Man man = new Man();
ManDecoratorA md1 = new ManDecoratorA();
ManDecoratorB md2 = new ManDecoratorB();
md1.setPerson(man);
md2.setPerson(md1);
md2.eat();
}
}
编译运行结果如下:
男人在吃再吃一顿饭ManDecoratorA类===============ManDecoratorB类
问题:我不明白的是,为什么只调用md2中的eat方法,ManDecoratorA类中的内容会输出来。
我自己分析了一下,在ManDecoratorB的eat方法里调用了父类的eat方法(super.eat());而在Decorator类中调用的是person.eat();这里md1.setPerson(man);所传的参数是man,所以也就是调用了man.eat();方法,这样会输出“男人在吃”。后面的就不明白了。Man类和ManDecoratorA类似乎一点关系也没有(除了都实现了Person接口)。ManDecoratorA类跟ManDecoratorB类除了只是都继承了Decorator抽象类之外,也没有别的关系了。那么ManDecoratorA类中的eat方法究竟是如何被调用的呢?
请教大神详细解释,不胜感激!
作者:
月光海
时间:
2014-4-16 11:26
你自己的分析我没看,我看了下代码,因为 md1.setPerson(man);md2.setPerson(md1);这两句你md2里传入的是md1,所以md2中的eat方法中的person其实是md1,所以就是调用了md1的eat方法,然后同样,md1中的eat方法中的person是man,所以会调用man的eat方法,为什么会打印A类,是因为你调用了md1的eat方法,方法中有打印A类,所以打印A类是必然的
作者:
月光海
时间:
2014-4-16 11:30
想不打印A类就直接设置md2.setPerson(man);这样就真的和A类没关系了
作者:
水竹
时间:
2014-4-16 11:41
执行md2.eat();
也就是——
super.eat();
System.out.println("==============="); System.out.println("ManDecoratorB类");
看那句super.eat();它找的是Decorator类中的那个person.eat();也就是要调用成员变量的eat方法。
这是类中说的,具体到主方法的实现当中,md2的那个Person类型的成员变量是md1,所以调用md1的eat();方法。
即:
super.eat();
reEat(); System.out.println("ManDecoratorA类");
System.out.println("===============");
System.out.println("ManDecoratorB类");
后面你就知道了,不说了。其实前边你也应该知道的,因为都是一个道理么,怎么可能后面知道前面没搞清楚。
复制代码
作者:
曹冬明
时间:
2014-4-16 11:56
标题:
1
本帖最后由 曹冬明 于 2014-4-16 11:57 编辑
md2中的person是md1,md1中person是man,md2.eat()这里的super.eat()调用的是md1.eat(),md1.eat()这里的super.eat()调用的是man.eat(),这样条理就出来了。执行顺序就是man.eat()-->md1.eat()-->md2.eat()的最后两条语句,输出的结果就是你看到的结果,还有不懂的话就@我咯- -
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2