1

Javaで非表示がどのように機能するかを理解したいと思います。それで、あなたが次のコードを持っていると仮定しましょう

public class A{
    protected SomeClass member;
    public A(SomeClass member){
        this.member = member;
    }
}  

public class B extends A{
    protected SomeClass member;
    public B(SomeClass member){
        super(member);
    }
    public static void main(String[] args){
        SomeClass sc = new SomeClass();
        B b = new B(sc);
        System.out.println(b.member.toString());
    }
}

コンパイルすると、NullPointerExceptionが発生します。sc.toString()の出力になると思いました。

このコードを次のように変更します

public class A{
    protected SomeClass member;
    public A(SomeClass member){
        setMember(member);
    }
    public void setMember(SomeClass sc){
       this.member = sc;
    }

}  

public class B extends A{
    protected SomeClass member;
    public B(SomeClass member){
        super(member);
    }
    public void setMember(SomeClass sc){
       this.member = sc;
    }
    //...main
}

そしてそれは期待通りに出力を取得します...oksetMember of B Aからのものをオーバーライドするので、これをこのように説明することができます。少し遊んで、BからsetMemberを削除して、NullPointerExceptionを取り戻しました。しかし、Aのコードを次のように変更すると、再度コンパイルされて出力が返されます。

public class A{
    protected SomeClass member;
    public A(SomeClass member){
        setMember(member);
    }
    public void setMember(SomeClass sc){
       member = sc;
    }

} 

実際にはSomeClassメンバーのインスタンスが2つあるように見えますが、インスタンスが2つある場合、シャドウイングとはどういう意味ですか?非表示は2番目の場合にのみ役立ちますか?

4

1 に答える 1

3

最初のコードサンプルの最後の行がであると仮定しますb.member.toString()

「member」という名前の2つのメンバー変数があり、どちらの例でも、1つの割り当てのみthis.memberが呼び出されているため、そのうちの1つだけが設定されています。最初の例を修正するには、通常、

public B(SomeClass member) {         
    super(member);
    this.member = member;
} 

しかし、あなたはすでにそれを理解していて、なぜ言語がこのように設計されているのかを本当に尋ねていると思います。これは、スーパークラス実装のカプセル化と関係があります。スーパークラスの作成者は、サブクラスを壊すことなくそれを書き直すことができ、その逆も可能です。B.member「メンバー」が周りにいるのは良いことですが、Bの作者が最初に来たとしたら、後でAの作者も同じ考えを持っていたと想像してみてください。

ただし、このシステムは完全ではありません。2番目の例はその理由を示しています。B.setMember()最初に来て、その後のバージョンのAが導入した場合、Aの作成者はオーバーライドメソッドA.setMember()を予期できず、コンストラクターを表示どおりに記述できず、結果が初期化されない可能性があります。C#はこの種のものをキャッチするために「overrides」キーワードを導入し、Javaはそれを「@overrides」として借用しましたが、そのアノテーションはJavaでは必須ではないため、それほど効果的ではありません。B.setMember()A.member

于 2011-06-24T21:26:22.477 に答える