2016-09-11 6 views
0

私はこのシナリオを持っている:スコープの問題。方法を参照する方法?

public class A 
{ 
    private final Integer index; 

    public Integer getIndex() { return index; } 

    public static class B 
    { 
    //unimportant 
    } 
} 

public class C extends B 
{ 
    //how to reference getIndex() here? 
} 

どのように私はクラスCの体内のgetIndex()を呼び出すことができますか?

答えて

0

できません。 CBgetIndex()メソッドを持たない。 Cは、そのメソッドを継承するためにAを拡張する必要があります。

3

奇妙なシナリオですが、クラスCをクラスAの内部クラスにする必要があります。なぜあなたは内部のクラスを最初から拡張していますか?これを引き起こしているデザインの制限は何ですか?あなたを全く見ない。設計の背後にある考え方は、おそらく代替の解決法を見つけるのに役立つだろう。

public class A 
{ 
    // make sure final value is set here or in constructor 
    private final Integer index = 0; 

    public Integer getIndex() { return index; } 

    public static class B 
    { 
     //unimportant 
    } 

    //Doesn't make much sense... but... 
    public class C extends B 
    { 

     //can now call getIndex() 
     public void callGetIndex() { 
     getIndex(); 
     } 

    } 
} 

ボーナス調査:私と多分として好奇心旺盛であり、他のファイルから関数を参照するためにこれを使用して考えたものについては 。 CがBを拡張していても、それはまだそのためで囲まする必要があるため動作しません

A.this.getIndex(); 

悲しい:あなたは別のファイルにCをコンパイルし、囲みこのを使用してgetIndexにアクセスしようとした場合働く方法論。クールねえ

C.java:5: error: not an enclosing class: A 
     A.this.getIndex(); 
     ^
1 error 

:あなたは、このコンパイル時エラーが発生します!次の@ mzlの答えに基づいた別の答え: 面白いことに、Bを静的に保ち、両方のクラスを拡張して、やりたいことを得ることができます。たとえば、A.javaが第三者の機能であるため、ファイルA.javaを編集できない場合に便利です。 (ここで彼の答えは@mzlのクレジットをここに記入してください)

このようにしてください!私はフロー・プロジェクトが証明オーバー静的に作成した

public class C extends A 
{ 

    public class D extends A.B { 
     //can now call getIndex() 
     public void callGetIndex() { 
      getIndex(); 
     } 

    } 

} 

A.java

public class A 
{ 
    private final Integer index = 0; 

    public Integer getIndex() { return index; } 

    public static class B 
    { 
    //unimportant 
    } 

} 

C.javaを(テスト済みこれは、javacのA.java C.javaを経由してコンパイル)@ mzlの理論はこちらです: https://github.com/davethomas11/stackoverflow_Q_39441077

ゴスチャが1つです。 Dの前にCのインスタンスを作成して、getIndex()へのアクセスがあることを確認します。 Dを直接インスタンス化して後で実行し、結果を投稿するとどうなるかはテストしていません。


このインスタンス化されたDの直接テストでは、後で更新されます。

私は私の静的なmain関数内でC.D testD = new C.D();を追加しました:

$ sh build.sh 
StackOverflowQuestion39441077.java:5: error: an enclosing instance that contains C.D is required 
     C.D testD = new C.D(); 
        ^
1 error 

をコンパイラは、私たちがこれを実行させないことで私たちを支援します。

0

(私はそれが面白い理論的な問題であると感じますが、実際にはほとんど意味を持つ。)

あなたはBからイベントアクセスA.getIndexをすることはできませんBは静的であり、そしてgetIndexはありませんので、あなたが必要とするgetIndexを起動するので、 Aのnull以外のインスタンス

あなたのスキームは、矛盾になるので、あなたはBは非静的、あなたはどちらかできなかっ作ることができると仮定すると:

  • 一方では、クラスBはので、新しいオブジェクトに、以前の非をインスタンス化するために、内部で
 
    A a=new A(); 
    B b=a.new B(); 
  • しかし、一方では、クラスCはトップLEVです:Aのヌルインスタンスが必要ですel(内部ではない)クラスであるため、直接インスタンス化することができます。ただし、Bのサブクラスであるため、スーパークラスと同じ制限が適用されます。Aのインスタンスが必要です。矛盾する!

私はそれを動作させるために考える唯一の方法は、getIndex静的を宣言することですので、Aのインスタンスは、(実際には、Bからどちらのサブクラス化が問題になります)必要ないであろう。

1

内部クラスを(非静的に)拡張する場合は、外部クラスも拡張する必要があります。

あなたは、このようにそれを行うことができます:

public class A 
{ 
    private final Integer index; 

    public Integer getIndex() { return index; } 

    public static class B {} 
} 

public class D extends A{ 

    public class C extends B{} 
} 
+0

これは良いデザインソリューションです! –

+1

奇妙なことに、Bは静的に留まることができ、ここであなたのメソッドを使用して、コンパイルしている実用的なソリューションを得ることができます。ファイルAの実装を変更できないためにBを拡張しようとしていると、彼は自分が望むことをすることができるからです。 AのBが静的であるときにクラスDの中のgetIndexにアクセスできるならば、クラスCは静的ではないからです。ちょうどクラスBは静的なので、拡張クラスも静的でなければなりません。 –

+0

あなたはまったく正しいです。ありがとう!私はあなたの提案に従って私の答えを編集しました。 – mzl

関連する問題