请教个基础的 Java 问题

2018-03-05 14:30:35 +08:00
 gaocc

先贴上代码,这里直接复制了,可能没有格式,有老司机知道怎么正确贴代码的请告知,谢谢!

/**

public class TestDecorator {

public static void main(String[] args) {
	Persion persion = new Persion("张三");
	Persion cpersion = new DecoratorClothes(persion);
	Persion ppersion = new DecoratorPants(cpersion);
	Persion spersion=new DecoratorShoes(ppersion);
	spersion.show();
}

}

/**

public class Persion {

public Persion() {
	super();
}

public Persion(String name) {
	System.out.print(name);
}

public void show(){};

}

/** *定义装饰者 */

public class Decorator extends Persion {

private Persion persion;

public Decorator() {
	super();
}

public Decorator(Persion persion) {
	this.persion = persion;
}

@Override
public void show() {
	persion.show();
}

}

public class DecoratorClothes extends Decorator {

public DecoratorClothes() {
	super();
}
//super()最近的一个父类,super 相当于是指向当前对象的父类,super (参数),调用父类中的某一个构造函数。
public DecoratorClothes(Persion persion) {
	super(persion);
}

/**
 * 装饰动作
 */
@Override
public void show() {
	super.show();
	wearClothes();
}

private void wearClothes() {
	System.out.print(" "+"穿衣服");
}

}

public class DecoratorPants extends Decorator {

public DecoratorPants() {
	super();
}

public DecoratorPants(Persion persion) {
	super(persion);
}

@Override
public void show() {
	super.show();
	wearPants();
}

private void wearPants() {
	System.out.print(" "+"穿裤子");
}

}

public class DecoratorShoes extends Decorator {

public DecoratorShoes() {
	super();
}

public DecoratorShoes(Persion persion) {
	super(persion);
}

@Override
public void show() {
	super.show();
	wearShoes();
}

private void wearShoes() {
	System.out.print(" "+"穿鞋子");
}

}

最后执行 show 方法,debug 执行顺序是:

1:DecoratorShoes 的 show 方法,执行第一行 super.show();

2:Decorator 的 show 方法,执行第一行 persion.show();

3:DecoratorPants 的 show 方法,执行第一行 super.show();

4:Decorator 的 show 方法,执行第一行 persion.show();

5:DecoratorClothes 的 show 方法,执行第一行 super.show();

6:Decorator 的 show 方法,执行第一行 persion.show();

7:DecoratorClothes 的 wearClothes 方法

8:Decorator 的 show 方法,执行最后的"}"

9:DecoratorPants 的 wearPants 方法

10:Decorator 的 show 方法,执行最后的"}"

11:DecoratorShoes 的 wearShoes 方法

12:结束

输出结果如下:

张三 穿衣服 穿裤子 穿鞋子

这是小子在回顾设计模式时写的 demo,从原书的 c++案例改的 java,通过重写装饰类的 show 方法,并在方法内执行需要附加的方法,完成动态的装饰效果。

小子有两处不太理解:

一是执行顺序,先 new 的对象是 DecoratorClothes,为什么测试类执行 show 方法先调用的却是 DecoratorShoes 的 show 方法?最后调用顺序却又按照了 new 对象的顺序又是为什么?小子粗略猜测是堆栈的原因,但具体要请教各位 geek 了。

二是测试类的 new 对象方式像是套用在一起,最后 new 得到的对象只执行了一次 show 方法却能分别执行三个具体装饰类的 show 方法,这是为什么,记忆上知道能这么干,但逻辑上不太理解原因,是 java 的哪个特性做到的?多态?

2008 次点击
所在节点    Java
5 条回复
sundae91
2018-03-05 19:33:02 +08:00
super.show()
wearXXX();
第一次调用 shoes 因为 person 的是其实例;之后调用顺序就是在上两行代码中间插入父类方法,类似:
super.show()
super.show()
super.show()
wearXXX();
wearXXX();
wearXXX();
每上一层,person 的实例都不同。
bxb100
2018-03-05 19:39:22 +08:00
你再跑下 debug 下 show 的运行流程就懂了
gaocc
2018-03-06 09:17:59 +08:00
@sundae91 感谢回答,怎么个流程我 debug 跑了,知道,不明白的是先后问题,比如为什么是先 DecoratorShoes 类的 show 方法,而不是先 DecoratorClothes 类的 show 方法。还有第二个问题怎么理解下?
sundae91
2018-03-06 09:24:47 +08:00
@gaocc 你 debug 的时候,每次调用 show 方法,查看下当前 person 对象是属于哪个类的实例
gaocc
2018-03-06 09:57:59 +08:00
@sundae91 是三个不同的类,这我也看了。关键还是顺序问题,很不好理解

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/434953

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX