成员对象调用类方法

时间:2015-01-08 17:40:44

标签: java oop interface

我希望这个问题不是现有问题的重复!我搜索过,发现我的问题没有很好的答案。这是:

我有一个包含Button成员对象的MyGame类。只要点击该按钮,MyGame就应该做点什么。

class MyGame extends Application {
    MyBoard board = new MyBoard();
    MyButton btn = new MyButton();

    public MyGame() {
        board.add(btn);
    }

    // this method should be called whenever the button is clicked!
    public void doSomething() {
        doingSomething();
    }
}

class MyButton extends Button {
    int someData;

    // some code here

    public MyButton() {
        this.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent arg0) {
                MyGame.doSomething();  // ==> NOT POSSIBLE!!!
            }
        });
    }
}

界面是否是MyButton和MyGame之间进行通信的最佳方式?如果是这样,你会怎么做?

我不想将MyGame对象的引用移交给MyButton对象!我认为这不是解决这个问题的好方法。

我感谢任何建议和帮助!

干杯

3 个答案:

答案 0 :(得分:3)

MyGame的构造函数中,您可以添加ActionListenerbtn,当对该按钮执行操作时将调用该btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // Insert thing to do within MyGame here } });

{{1}}

答案 1 :(得分:1)

一种方法是反过来做(游戏应该是按钮的成员)。我知道你认为“这不是一个解决这个问题的好方法”,但你认为错了,它确实没有错。

或者,将监听器的注册从按钮的构造函数中移出到游戏本身:

public MyGame() {
   btn.setOnAction(new EventHandler<ActionEvent>() {
       public void handle(ActionEvent arg0) { doSomething(); }
   });
}

答案 2 :(得分:1)

进行&#34;按钮操作&#34;创建MyButton时可以传递给构造函数的接口。例如:

public MyButton(final Runnable action) {
    this.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent arg0) {
            action.run();  // POSSIBLE!!!
        }
    });
}

或将操作保存在MyButton实例字段中:

public MyButton(Runnable action) {
    buttonAction = action;     // make buttonAction an instance field
    this.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent arg0) {
            buttonAction.run(); 
        }
    });
}

然后当MyGame创建新的MyButton时,MyGame会告诉按钮点击按钮时该怎么做:

MyButton btn = new MyButton(new Runnable() {
    @Override
    public void run() {
        MyGame.this.doSomething();
    }
}

或Java 8:

MyButton btn = new MyButton(this::doSomething);

注意:我还没有测试过这个。我认为我的语法正确,但我可能犯了一个错误。您可能需要在btn构造函数中而不是在初始化表达式中指定MyGame

这是一种广泛的方法(依赖注入?),适用于很多情况。可能存在特定于Button的其他解决方案(或已经为其定义了侦听器机制的其他Swing组件)。但是这种机制减少了耦合,因为MyButton并不真正需要了解创建它的人,而MyGame并不需要知道MyButton是什么计划采取Runnable行动。其他一些可能的解决方案涉及让MyGame做一些MyButton的工作,这会增加耦合。