4

サブクラスはまだ構築されていないため、スーパークラスのコンストラクターで抽象メソッドを呼び出すのは安全ではありませんか?

ただし、メソッドの動作がサブクラスの構成に依存しない場合、たとえば、サブクラスに関して定数を返すだけの場合、それはまだ安全ではないのでしょうか、それとも確実に動作しますか?

さらに、それが機能する場合、スーパークラスを抽象化したくない場合はどうすればよいですか?

更新:最後の質問について

public class SuperClass {
      public SuperClass() {
          System.out.println(getValue());
      }   

      public String getValue() {
          return "superclass";
      }   

      public static void main(String[] args) {
           new SubClass();
      }

}


class SubClass extends SuperClass {
      public SubClass() {
           super(); // Comment out this or not  will not affect the result
      }   

      public String getValue() {
           return "subclass";
       }   
}

私はテストを書き、それを理解しました:結果は次のとおりです: subclass @Tim Poteの例に感謝します。

4

2 に答える 2

4

一般的に(必ずしもそうとは限りませんが)安全でないと見なされます。あなたが言ったように、スーパークラスは完全に構築されていない可能性があり、したがって、サブクラスがそのオーバーライドされたメソッドで行う可能性のあるすべての呼び出しを処理する準備ができていません。

ただし、すべてのサブクラスが他のメソッドに依存しない定数を返すだけの場合は、問題ないはずです。唯一の欠点は、サブクラスがそのメソッドを適切な方法でオーバーライドすることを保証できないことです。

あなたの最後の質問に関して:これは抽象的対具体的なスーパークラスの問題ではありません。これは、コンストラクターでオーバーライド可能なメソッドを呼び出す際の問題です。抽象的対具体的は重要ではありません。


OPのコメントに応じて編集する

「多形性」とはどういう意味かわかりません。仮想メソッドを呼び出すと、常にサブモストの実装が呼び出されます。スーパークラスの実装が呼び出されるのは、superキーワードを使用する場合のみです。例えば:

public class SuperClass {
  public SuperClass() {
    System.out.println(getValue());
  }   

  public String getValue() {
    return "superclass";
  }   

  public static void main(String[] args) {
    new SubClass();
  }   

  public static class SubClass extends SuperClass {
    public String getValue() {
      return "subclass";
    }   
  }   
}

印刷しsubclassます。

この:

public class SuperClass {
  public SuperClass() {
    System.out.println(getValue());
  }   

  public String getValue() {
    return "superclass";
  }   

  public static void main(String[] args) {
    new SubClass();
  }   

  public static class SubClass extends SuperClass {
    public String getValue() {
      return super.getValue() + " subclass";
    }   
  }   
}

プリントsuperclass subclass

于 2012-11-15T03:31:21.130 に答える
1

他の人が説明したように、スーパークラスコンストラクターで抽象メソッドを呼び出すには固有のリスクがあります。

私が見つけた1つの例外は、サブクラスが「一定の」情報、たとえば などを提供する場合getId()ですgetHandledMessages()

于 2012-11-15T03:34:45.670 に答える