V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gaocc
V2EX  ›  Java

请教个基础的 Java 问题

  •  
  •   gaocc · 2018-03-05 14:30:35 +08:00 · 2026 次点击
    这是一个创建于 2473 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    /**

    • 装饰者与被装饰者可以拥有共同的超类,继承的目的是继承类型,而不是行为 */

    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 的哪个特性做到的?多态?

    5 条回复    2018-03-06 09:57:59 +08:00
    sundae91
        1
    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
        2
    bxb100  
       2018-03-05 19:39:22 +08:00
    你再跑下 debug 下 show 的运行流程就懂了
    gaocc
        3
    gaocc  
    OP
       2018-03-06 09:17:59 +08:00
    @sundae91 感谢回答,怎么个流程我 debug 跑了,知道,不明白的是先后问题,比如为什么是先 DecoratorShoes 类的 show 方法,而不是先 DecoratorClothes 类的 show 方法。还有第二个问题怎么理解下?
    sundae91
        4
    sundae91  
       2018-03-06 09:24:47 +08:00
    @gaocc 你 debug 的时候,每次调用 show 方法,查看下当前 person 对象是属于哪个类的实例
    gaocc
        5
    gaocc  
    OP
       2018-03-06 09:57:59 +08:00
    @sundae91 是三个不同的类,这我也看了。关键还是顺序问题,很不好理解
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3178 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 73ms · UTC 05:01 · PVG 13:01 · LAX 21:01 · JFK 00:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.