0

サブクラスがスーパークラスを継承する場合、サブクラスと、スーパークラスで定義された異なるアクセシビリティを持つフィールドとの関係、サブクラスが所有するフィールドと所有しないフィールドはどうなりますか。そして、誰かが以下の例を説明できますか:

class Parent
{
  private int partOne = 0;
  public int partTwo = 1;

  public void tellMe()
  {
     System.out.println(partOne);
     System.out.println(partTwo);
  }
}
class Child extends Parent
{
  private int partOne = 2;
  public int partTwo = 3;

  public void main(String[] args)
  {
   Child child = new Child();
   child.tellMe();
  }
}

Eclipse でデバッグしたとき、スタック内の変数childを監視しました。Child インスタンスには 4 つのフィールドがあり、そのうちの 2 つはそのクラスによって定義され、2 つはその親クラスによって定義されていることがわかりました。私は非常に混乱しました。子インスタンスを作成する IMP 、親クラスのコンストラクターに入るだけだと思いますが、子クラスが2つのフィールドをオーバーライドしない理由を説明できません、または少なくとも、partTwoパブリックアクセシビリティでオーバーライドする必要があると思います.理由を教えてください、ありがとう。

4

2 に答える 2

4

子クラスが2つのフィールドをオーバーライドしない理由、または少なくとも、パブリックアクセシビリティでpartTwoをオーバーライドする必要があると思います

Java では、データ メンバーはポリモーフィックではありません。これは、あなたの例では、クラスで定義された2 つのフィールドが、たまたま名前を共有していてもChild、クラスの 2 つのフィールドとはまったく関係がないことを意味します。Parent

これは言語によって許可されていますが、この性質のことを行うことは混乱のレシピに過ぎません (ご存じのとおり)。

ポリモーフィックな動作が必要な場合は、2 つのメンバー関数getPartOne()および を作成getPartTwo()し、必要に応じてオーバーライドします。

于 2012-05-26T13:14:09.407 に答える
0

クラスで同じ名前で再定義することによりpartTwo、クラスのフィールドへのアクセスを隠しています。実際には、それについてコンパイラから警告が表示されるはずです。ParentChild

次の実験を行って、何が起こっているかを確認します。

  • superのコンストラクターを呼び出して、両方のクラスに適切なコンストラクターを追加しますChild(はい、これは必須ではありませんが、わかりやすくするのに役立ちます)。
  • フィールド宣言で直接行うのではなく、コンストラクターでフィールドを初期化します。
  • これまでのところ、コードは同じことを行います。
  • partTwoここで変数をクラスから削除しますChild- コンパイルは続行されますが、今回はのコンストラクターによって設定された値Childが適用されます (警告は消えます)。

カプセル化について私が投稿したコメントを見たことがあるかもしれません。プライベート フィールドのみを使用すると、継承クラスに影響を与えずにクラスのフィールドを変更できるため、このような混乱を防ぎ、後でクラスのメンテナンスを改善できます (メソッドがアクセスする限り)。データは変更されません)。

于 2012-05-26T13:15:18.563 に答える