0

具体的には、親クラスと子クラスの両方で宣言された変数が、引数が親クラスであるメソッドに渡された子クラスのインスタンスで非表示になるのはなぜですか?

これは、私を困惑させている問題の簡単な例です。親サブタイプと子サブタイプの 3 つのクラスがあります。クラスには、フィールドとしての Foo オブジェクトと、この静的な種類のファクトリ メソッドがあります。

class Parent {
    public Foo myFoo;

    public static ThinChild createThinChild(Foo someFoo) {
        ThinChild thinChild = new ThinChild(someFoo);
        return thinChild;
    }

    public Foo getFoo() {
        return myFoo;
    }
}

class ThinChild extends Parent {
    public Foo myFoo;

    public ThinChild(Foo someFoo) {
        myFoo = someFoo;
    }
}

class ThickChild extends Parent {
    public Foo myFoo;

    public ThickChild(Foo someFoo) {
        myFoo = someFoo;
    }
}

次に、このハンドラー クラスを考えてみましょう。

class ChildHandler {
    private void doSomethingToThinChild(ThinChild thinChild) {
        assert(thinChild.getFoo() != null);
        doSomethingToAllChildren(thinChild);
    }

    private void doSomethingToAllChildren(Parent thinOrThickChild) {
        assert(thinOrThickChild.getFoo() != null);
    }
}

を呼び出すdoSomethingToThinChildと、アサートが渡されます。しかし、メソッドdoSomethingToAllChildrenでは、アサートは失敗します。これは私が期待するものではありません。

さらに、クラスにあるのとまったく同じgetFooメソッドをParentクラスに追加するとThinChild、アサートが機能するようになりました。これは私の差し迫った問題を解決しますが、親で維持したい子クラスのそれぞれで同一のコードを維持している限り、私には望ましくないようです。

私の実際のケースはもう少し複雑ですが、関連するすべての詳細を把握できたことを願っています。私が持っていると仮定すると、なぜこれが期待される動作になるのかについての説明はありますか?

ここに示していない実際のコードには、さらに複雑な問題がある可能性があります。しかし、最初に、Java でのクラス継承に関する私の理解が正しいことを確認したいと思います。

ありがとう。

4

2 に答える 2

1

を削除しpublic Foo myFooます。ネストされたクラスでは、このフィールドは親クラスから拡張されます。同じ名前の変数が2つあるため、変更できません。そのため、JVMはより小さなスコープで変数を初期化しました。

また、親でコンストラクターを作成するのも良い方法です。

public Parent(Foo someFoo) {
    myFoo = someFoo;
}

次に、それをサブクラスで呼び出します。

public ThinChild(Foo someFoo) {
    super(someFoo);
}
于 2012-05-26T22:18:43.650 に答える
1

myFoo は直接の子クラスから見えるので、「super.myFoo」で修飾するだけです。ただし、これはチェーンの 1 レベル上にしか機能しません。そのため、ThinChild に myFoo を持つサブクラス ThinnerChild もある場合、親クラスに存在する「myFoo」のインスタンスに到達できませんでした。自分の行動を親でオーバーライドできるようにする必要がありますが、親をオーバーライドすることはできません (したがって、super.super のようなものは許可されません)。

つまり、この場合、ThinChild と ThickChild にはそれぞれ 2 つの "myFoo" インスタンスがあり、1 つはそれに属し、もう 1 つはその親に属しているため、子クラスのインスタンスを削除することが最も可能性が高いです。

于 2012-05-27T05:35:26.753 に答える