Java可以继承继承并覆盖嵌套类吗?

时间:2015-11-04 18:32:25

标签: java swing inheritance subclass nested-class

这适用于Java Swing JToolBar:

我有自己的Toolbar类,它扩展了JToolBar,它上面有ActionListeners的按钮。代码:

class ToolBar extends JToolBar {
    JButton save, reset;

    ToolBar() {
        setFloatable(false);
        setRollover(true);
        makeButtons();
    }

    makeButtons() {
        save = new JButton();
        // Icon and tooltip code
        save.addActionListener(new ButtonListener());
        add(save);

        reset = new JButton();
        // Icon and tooltip code
        reset.addActionListener(new ButtonListener());
        add(reset);

    protected class ButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
        }
    }

然后我做了一些其他的子类,因为我需要多个工具栏用于多个帧,每个工具栏都有不同的“保存”或“重置”源/目标。我只是简单地给出一个:

class FullToolBar extends ToolBar {

    protected class ButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            if (event.getSource() == save) FullInput.save();
            else if (event.getSource() == reset) FullInput.reset();
        }
    }
}

FullInput是我的一个JFrame的名称,工具栏将继续存在。它有一个静态的保存和重置方法,但由于某种原因,当我将FullToolBar添加到我的FullInput时,按钮不起作用。

我是否误解了嵌套类可以继承和覆盖?任何想法/评论,甚至是完全不同的方式来做我想在这里完成的事情的建议?基本上,需要一种方法来使用相同工具栏的不同框架/类上的保存和重置按钮。

2 个答案:

答案 0 :(得分:3)

不,你不能覆盖那样的嵌套类。有几种方法可以解决这个问题。一种方法是将可重写方法放在主工具栏类上,​​例如:

class ToolBar extends JToolBar {

  makeButtons() {
    save = new JButton();
    // Icon and tooltip code
    save.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        saveButtonPressed(event);
      }
    });
  }

  protected void saveButtonPressed(ActionEvent event) {}
}

然后,通过覆盖saveButtonPressed方法,子类可以在按下保存按钮时自定义操作。

答案 1 :(得分:3)

  

我是否误解了嵌套类可以继承并覆盖?

是。虽然您的ButtonListener类具有相同的名称,但它们之间没有其他连接。嗯......嵌套类是继承的,但它们不能被覆盖。例如,您可以继承继承的类:

class FullToolBar extends ToolBar {
    protected class ButtonListener extends ToolBar.ButtonListener {
                                           ^^^^^^^^^^^^^^^^^^^^^^

但这并不是很有用,因为它仍然无法在new ButtonListener()覆盖ToolBar的来电。

还有很多其他方法可以完成这项工作。如果你真的想要覆盖ButtonListener类,你可以用new ButtonListener()的方法替换对方法protected ActionListener createListener()的调用,以便在子类中重写,这样它们就可以提供他们想要的任何监听器类实现。在这种情况下,这可能会使它过于复杂。

这里更简单的解决方案是直接使ToolBar实现ActionListener,并覆盖子类中的actionPerformed方法:

class ToolBar extends JToolBar implements ActionListener {
    ...

    void makeButtons() {
        ...
        save.addActionListener(this);
        ...
    }

    public void actionPerformed(ActionEvent event) {
    }
}

class FullToolBar extends ToolBar {
    @Override
    public void actionPerformed(ActionEvent event) {
        if (event.getSource() == save) FullInput.save();
        else if (event.getSource() == reset) FullInput.reset();
        else super.actionPerformed(event);
    }
}

作为对此的修改,如果您希望阻止actionPerformedToolBar中公开,请改为使用受保护的方法,命名您想要的任何内容,并在子类中覆盖它。使用Java 8的方法参考语法将处理程序方法与按钮连接:

class ToolBar extends JToolBar {
    ...

    void makeButtons() {
        ...
        save.addActionListener(this::onButtonClick);
        ...
    }

    protected void onButtonClick(ActionEvent event) {
    }
}

class FullToolBar extends ToolBar {
    @Override
    protected void onButtonClick(ActionEvent event) {
        if (event.getSource() == save) FullInput.save();
        else if (event.getSource() == reset) FullInput.reset();
        else super.onButtonClick(event);
    }
}

另一个想法是:你真的需要ToolBar设置这些按钮的事件监听器吗?您可以在子类中执行此操作:

class ToolBar extends JToolBar {
    ...

    protected void makeButtons() {
        save = new JButton();
        add(save);
        reset = new JButton();
        add(reset);
    }
}

class FullToolBar extends ToolBar {
    @Override
    protected void makeButtons() {
        super.makeButtons();
        save.addActionListener((ActionEvent e) -> FullInput.save());
        reset.addActionListener((ActionEvent e) -> FullInput.reset());
    }
}