0

假设我想装饰一个继承受保护的可观察字段的类。如何访问该受保护变量,以便扩展所述超类的功能?

请参阅下面更具体的示例。

Class SuperSuper - 最初包含匿名观察者的类

package javafxapplication1;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class SuperSuper extends Application {

    protected Button button = new Button();

    @Override
    public void start(Stage stage) throws Exception {
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                doSomething();
            }
        });
    }

    public String doSomething() {
        return "1";
    }
}

Class Super - 继承匿名观察者的超类

package javafxapplication2;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafxapplication1.SuperSuper;

public class Super extends SuperSuper {

    @Override
    public void start(Stage stage) throws Exception {
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                doSomething();
            }
        });
    }

    @Override
    public String doSomething() {
        return "2";
    }
}

Class SuperDecorator - Super 的装饰器类

package javafxapplication3;

import javafxapplication2.Super;


class SuperDecorator extends Super {
    Super zuper;

    public SuperDecorator(Super zuper){
        this.zuper = zuper;
    }

    @Override
    public String doSomething() {
        return zuper.doSomething()+"3";
    }

    //What should I put here in order to make zuper's button print 3?
}
4

1 回答 1

2
//What should I put here in order to make zuper's button print 3?

为了满足您的要求,您不需要Super装饰,只要extends可以正常工作:

class SuperDecorator extends Super {
    @Override
    public void doSomething() {
        System.out.println("3");
    }
}

然后打电话new SuperDecorator().doSomething()

理想情况下,装饰器实现应该通过interface,您的修改方法是正确的,尽管extends仍然不能很好地工作,因为在装饰期间您将如何使用继承,因为方法被委托给zuper并修改结果 ( decorated)。考虑以下替代方案:

public class SuperSuper extends Application implements IActionPerformer {
            @Override
public void start(Stage stage) throws Exception {
    button.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent t) {
            doSomething();
        }
    });
}

        public String doSomething() {
            return "1";
        }
    }

    public class Super extends SuperSuper {
        public String doSomething() {
            return "2";
        }
    }

    abstract class AbstractSuperDecorator implements IActionPerformer {
        protected IActionPerformer zuper;
        public AbstractSuperDecorator(IActionPerformer zuper) {
            this.zuper = zuper;
        }
        public String doSomething() {
            return zuper.doSomething();
        }
    }

    public class Super3Decorator extends AbstractSuperDecorator {
        public Super3Decorator(IActionPerformer zuper) {
            super(zuper);
        }
        public String doSomething() {
            return super.doSomething()+"some-val"; //decoration
        }
    }

注意:了解这种差异,您的装饰是围绕doSomething它移出的interface,而不是围绕startbuttonstart依赖doSomething是隐式的(实现驱动),它不是装饰参与者。

于 2013-10-22T08:01:52.277 回答