Украшение класса, который наследует защищенную наблюдаемую
Допустим, я хочу украсить класс, который наследует защищенное наблюдаемое поле. Как я могу получить доступ к этой защищенной переменной, чтобы я мог расширить функциональность указанного суперкласса?
Пожалуйста, посмотрите более конкретный пример ниже.
Класс 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";
}
}
Класс SuperDecorator - Супер декоратор класса
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?
}
1 ответ
//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
, не рядом start
или же button
, start
зависимость от doSomething
является неявным (управляемым реализацией) и не является участником оформления.