0

在超类的构造函数中,我有通向其他子类的按钮。然而,这些子类也继承了这些按钮,即使它们不在它们的构造函数中。如何从我的子类中删除这些按钮?我正在使用 javax.swing。

好的,这是一个代码示例。我很确定我在做 OOP 完全错误......

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;

public class Big extends JFrame implements ActionListener
{
    static private JPanel p1;
    static private JButton b1;    
    public Big(){    
        setSize(700,400);
        p1 = new JPanel();
        b1 = new JButton("Go to subclass");
        b1.addActionListener(this);
        p1.add(b1);
        add(p1, BorderLayout.NORTH);
        setVisible(true);
    }

    public void actionPerformed (ActionEvent e){
        if(e.getSource() == b1){
            setVisible(false); 
            Small subclass = new Small();
        }
    }
}

第二类:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;


public class Small extends Big implements ActionListener
{
    static private JButton b2;
    static private JPanel p2;
    public Small(){    
        setSize(700,400);
        p2 = new JPanel();
        b2 = new JButton("Hello!");
        p2.add(b2);
        add(p2, BorderLayout.SOUTH);
        setVisible(true);
    }
    public void actionPerformed (ActionEvent e){}
}
4

3 回答 3

2

根据您发布的代码,我认为没有理由使用继承。我建议你根本不继承,问题就会消失。

还:

  • 不要使用静态变量。
于 2013-10-26T20:40:47.047 回答
1

OOP 意义上的继承与类构造函数中的代码无关。事实上恰恰相反。在构造函数和其他方法外声明的变量是被继承的,在构造函数内声明的变量是被继承的。

但是,是的,在其构造函数中添加到 Component 或 JComponent 的对象将被子类“继承”(但不是 OOP 意义上的继承一词),除非它们在子类中被删除。因此,解决此问题的一种快速、有点笨拙的方法是通过调用子类再次删除它们remove

我不会那样做。更好的方法可能是createButtons在超类中调用一个方法,并在子类中重写它以不执行任何操作,但如果您这样做,请注意不要在它存在之前引用任何内容。

但是根据您现在发布的代码,我认为在这里使用继承根本没有意义。

于 2013-10-26T20:10:23.367 回答
1

构造函数必须始终调用超类的构造函数作为他们做的第一件事。如果你没有明确地写这个,编译器会自动插入调用(假设在超类中有一个无参数的构造函数来调用;否则它需要你自己做)。所以 Small 的构造函数的实际开头是这样的:

public Small() {
    super(); // call Big() constructor
    setSize(700,400);
    ...

这就是为什么它似乎继承了按钮“即使它们不在它们的构造函数中”。

您可以规避这种情况的一种方法是将创建面板和按钮的代码移动到您可以覆盖的 createGUI() 方法中。与构造函数不同,方法不必调用任何超类方法,如果它们不想:

public class Big extends JFrame implements ActionListener {
    ...

    public Big() {
        createGUI();
    }

    protected void createGUI() {
        // Init buttons of Big here.
    }
}

public class Small extends Big {
    // This constructor is optional; if you remove it, the
    // compiler will insert one that looks exactly like this.
    public Small() {
        super();
    }

    @Override
    protected void createGUI() {
        // Init buttons of Small here.
        // Big's constructor calls this method, but it has been overridden,
        // so Big's implementation of this method will not execute for
        // instances of Small (unless you call super.createGUI(); on purpose).
    }
}

我并不是说这种改变是一个好主意,我也不认为它是一个好主意。正如其他人所指出的,当 Small 似乎不想继承 Big 的代码、行为或字段时,它为什么会扩展 Big 尚不清楚。我只是想解释为什么超类按钮会出现。这是因为构造函数必须调用超类构造函数。

于 2013-10-26T21:28:39.513 回答