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();
        }
    }
}

2級:

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

コンストラクターは、常に最初にスーパークラスのコンストラクターを呼び出す必要があります。これを明示的に記述しない場合、コンパイラは呼び出しを自動的に挿入します (呼び出すスーパークラスに引数のないコンストラクターがあると仮定します。それ以外の場合は、自分で行う必要があります)。したがって、Small のコンストラクタの実際の始まりは次のようになります。

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

そのため、「コンストラクターに含まれていなくても」ボタンを継承しているように見えます。

これを回避する方法の 1 つは、パネルとボタンを作成するコードをオーバーライド可能な 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).
    }
}

私は、この変更が良い考えだと言っているわけではありませんし、そうではないと思います。他の人が指摘しているように、Big のコード、その動作、またはそのフィールドを継承したくないように見えるときに、なぜ Small が Big を拡張するのかは明らかではありません。スーパークラス ボタンが表示される理由を説明したかっただけです。これは、コンストラクターがスーパークラス コンストラクターを呼び出さなければならないためです。

于 2013-10-26T21:28:39.513 に答える
1

OOP の意味での継承は、クラスのコンストラクターにあるコードとは何の関係もありません。実際は逆です。コンストラクタおよび他のメソッドの外側で宣言された変数継承され、コンストラクタの内側で宣言された変数は継承されません

ただし、はい、コンストラクターでコンポーネントまたは JComponent に追加されたオブジェクトは、サブクラスで削除されない限り、サブクラスによって「継承」されます (ただし、継承という言葉の OOP の意味ではありません)。したがって、これを修正する手っ取り早いややハックな方法removeは、サブクラスを呼び出してそれらを再度削除することです。

それは私がそれをする方法ではありません。より良い方法createButtonsは、スーパークラスでメソッドを呼び出し、サブクラスでそれをオーバーライドして何もしないことですが、そのようにする場合は、存在する前に何かを参照しないように注意してください。

しかし、あなたが今投稿したコードに基づいて、ここで継承を使用することはまったく意味がないと思います。

于 2013-10-26T20:10:23.367 に答える