2

Java を「リフレッシュ」しようとしましたが、明らかに基本的な概念を理解していないことに気付きました! これは私が理解できない単純なものです:

public abstract class Robot {

    private String model = "NONAME";

    public Robot() {
        System.out.println("Making a generic " + model + " robot, type: " + this.getClass());
    }

    public String getModel() {
        return model;
    }
}

OK、そしてサブクラス:

public class Terminator extends Robot {
    private String model;

    public Terminator(String model) {
        super();
        System.out.println("Making a " + model + " terminator, type: " + this.getClass());
        this.model = model;
    }
}

次に、「T1000」が出力されることを期待して、簡単な例を実行します。

    Robot r1 = new Terminator("T1000");
    System.out.println(r1.getModel());

ダイスなし!「NONAME」がプリントされています。その前に、コンストラクターから次の出力を取得します。

  • 一般的な NONAME ロボットを作成するには、次のように入力します: class com.akarpov.tutorial.Terminator
  • T1000 ターミネータを作成するには、次のように入力します: class com.akarpov.tutorial.Terminator

さて、私のクラスの実行時インスタンスが Terminator であるという事実を Java が認識していることがわかります。そして、明らかに、Terminator インスタンスはモデル == "T1000" のコピーを保持します。しかし、デバッガー (IntelliJ) で r1 オブジェクトを調べると、「モデル」という名前の2 つの変数が、(明らかに) 異なるアドレスに、異なる文字列で表示されます。そして明らかに、出力が示すように、abstract クラスの getModel は、ターミネーターのコンストラクターに渡された (オブジェクト内に保持された) 値ではなく、Robot クラスで定義されたデフォルト値を取得します。

抽象クラスと継承について私が理解していないことは何ですか?また、サブクラスで特定のデータ (つまり「T1000」) を取得するデフォルト値とデフォルトの動作 (つまり getModel) をどのように設定すればよいでしょうか? ありがとう!そして、これが以前に何度も答えられた場合、私の謝罪-私は見ましたが、何も私に飛びつきませんでした.

4

4 に答える 4

2

あなたの問題はプライベート修飾子にあります...モデル変数は2つのクラスに別々に2回存在します。プライベートとは、そのクラスにのみ表示されることを意味します。setter メソッドを使用することもできます。

于 2013-07-06T17:58:23.340 に答える
1

ああ、私は投稿した直後にそれを手に入れました。私の間違いは、Terminator で別の String モデルを宣言したことでした。これにより、Robot でモデルが非表示になり、2 つのコピーが作成されました。それを削除すると、問題は解決しました。ああ!

于 2013-07-06T17:58:26.230 に答える
0

このコード行を見てみましょう

Robot r1 = new Terminator("T1000");

したがって、これは Terminator(String) コンストラクターを呼び出します。コンストラクターが最初に行うことは、スーパークラス コンストラクターを明示的に呼び出すことです。それは自動的に行われますが、super() を明示的に記述したので問題ありません。スーパークラス コンストラクターは 1 つのことを行います。

System.out.println("Making a generic " + model + " robot, type: " + this.getClass());

わかりましたので、「汎用 NONAME ロボットを作成しています。タイプ: ターミネーター」と出力されます。「モデル」変数へのローカル参照がないため、Robot クラス内で定義されたインスタンス変数を使用します。次に、制御が Terminator コンストラクターに戻され、出力に進みます。

System.out.println("Making a " + model + " terminator, type: " + this.getClass());

しかし今回は、メソッドを呼び出すクラスによってモデル変数が渡されたため、期待どおりに機能するため、インスタンス変数がシャドウされます。したがって、その値は「T1000」です。うまくいけば、それは理にかなっています

于 2013-07-06T18:03:04.203 に答える