Java 超类中的按钮仍在子类中

Java 超类中的按钮仍在子类中,java,swing,inheritance,Java,Swing,Inheritance,在超类的构造器中,我有一些按钮可以引导其他子类。但是,这些子类也继承这些按钮,即使它们不在其构造函数中。我如何才能从我的子类中删除这些按钮?我正在使用javax.swing 这是一个代码示例。我很确定我做的OOP是完全错误的 import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.util.*; public class Big extends JFrame implements ActionL

在超类的构造器中,我有一些按钮可以引导其他子类。但是,这些子类也继承这些按钮,即使它们不在其构造函数中。我如何才能从我的子类中删除这些按钮?我正在使用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){}
}
OOP意义上的继承与类构造函数中的代码无关。事实恰恰相反;在构造函数和其他方法之外声明的变量将被继承,而在构造函数内部声明的变量不会被继承

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

但我不会这么做。更好的方法可能是在超类中调用一个方法
createButtons
,并在子类中重写它,使其不做任何事情,但如果这样做,请注意不要在它存在之前引用任何东西

但是基于您现在发布的代码,我认为在这里使用继承毫无意义。

面向对象的继承与类构造函数中的代码无关。事实恰恰相反;在构造函数和其他方法之外声明的变量将被继承,而在构造函数内部声明的变量不会被继承

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

但我不会这么做。更好的方法可能是在超类中调用一个方法
createButtons
,并在子类中重写它,使其不做任何事情,但如果这样做,请注意不要在它存在之前引用任何东西


但是基于您现在发布的代码,我认为在这里使用继承毫无意义。

基于您发布的代码,我认为没有理由使用继承。我建议你干脆不继承遗产,问题就会迎刃而解

此外:

  • 不要使用静态变量

根据您发布的代码,我认为没有理由使用继承。我建议你干脆不继承遗产,问题就会迎刃而解

此外:

  • 不要使用静态变量

构造函数必须始终首先调用超类的构造函数。如果没有显式编写,编译器会自动插入调用(假设在超类中没有参数构造函数可调用;否则它要求您自己执行)。因此,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。我只是想解释为什么会出现超类按钮。这是因为构造函数必须调用超类构造函数。

构造函数必须始终首先调用超类的构造函数。如果没有显式编写,编译器会自动插入调用(假设在超类中没有参数构造函数可调用;否则它要求您自己执行)。因此,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。我只是想解释为什么会出现超类按钮。这是因为构造函数必须调用超类构造函数。

请添加一些代码。当你对超类进行子类化时,你不能从超类中删除东西。可能有办法解决这个问题,但如果没有您的代码,我们不知道您如何更改它。这闻起来可能是您不适当地使用了继承。你为什么要开始子类化这个类?他仍然可以在构造函数中使用buttonX.setVisible(false),但这可能不是问题的正确答案…@kmas添加了示例代码请添加一些代码。当你子类化它时,你不能从超类中删除东西。可能有办法解决这个问题,但如果没有您的代码,我们不知道您如何更改它。这闻起来可能是您不适当地使用了继承。你为什么要开始子类化这个类?他仍然可以在构造函数中使用buttonX.setVisible(false),但这可能不是问题的正确答案…@kmas添加了在构造函数外声明的示例代码变量是继承的,你是指类字段,对吗?那么简单,要解决这个问题,有点老套的方法是在IMOA子类中调用remove来再次删除它们