2011-11-15 23 views
1

次のJavaプログラムは、円の面積を計算するだけです。これは、Javaで利用可能な内部クラスの概念を使用します。内部クラス(FirstInner)の一つは、という名前のクラスを囲んだし、SecondInnerクラスが順番にFirstInnerを導出継承します。プログラムは正常に動作しています。まったく問題はありません。それを見てみましょう。 SecondInnerクラスで今Javaの包囲クラスから継承した内部クラス

package innerclass; 

import innerclass.Outer.SecondInner; // Need to be inherited. 
import java.util.Scanner; 

class Outer 
{ 
    protected double r; 

    public Outer() 
    { 

    } 

    public Outer(double r) 
    { 
     this.r=r; 
    } 

    public class FirstInner extends Outer 
    { 
     public FirstInner(double r) 
     { 
      super(r); 
     } 
    } 

    final public class SecondInner extends FirstInner 
    { 
     public SecondInner(double r) 
     { 
      Outer.this.super(r);  //<------------- 
     } 

     public void showSum() 
     { 
      System.out.print("\nArea of circle = "+(Math.pow(r, 2)*Math.PI)+"\n\n"); 
     } 
    } 
} 

final public class Main 
{ 
    public static void main(String[] args) 
    { 
     Scanner s=new Scanner(System.in); 
     System.out.print("\nEnter radius:->"); 
     double r=s.nextDouble(); 

     Outer o=new Outer(); 
     SecondInner secondInner = o.new SecondInner(r); 
     secondInner.showSum(); 
    } 
} 

、私はそれが単にちょうどのように見えますOuter.this.super(r);ようこのと再びで最初FirstInnerクラスであるスーパークラスの予選ですsuper(r);


のみsuper(r)ではなくOuter.this.super(r);の使用は、「スーパーコンストラクタがと呼ばれている前がこれを参照することができない」ことを示すコンパイラ時エラーが発生します。それはなぜそうですか?なぜOuter.this.super(r);super(r)ではなく使用しなければならないのですか?


もう一つのポイント私はFirstInnerクラスの静的作るとき、プログラムには、コンパイル時のエラーを発行しないとOuter.this.super(r);の代わりにちょうどsuper(r)を使用することができます。どうして?

+0

http://stackoverflow.com/questions/3383460/odd-situation-for-cannot-reference-this-before-supertype-constructor-has-been-c – Stefan

+0

super(r)の呼び出しは正常に動作するはずです。 FirstInnerのコンストラクタが呼び出されます。 正常でないコードを投稿できますか? –

+0

非動作コードは、ステートメントOuter.this.super(r); SecondInnerクラスのsuper(r)に置き換えられます。これは、上記の質問自体に示されているコンパイル時エラーを引き起こしません。 – Lion

答えて

1

ここに記載されている例を参照してください。

15.11.2 Accessing Superclass Members using super

のJava TUTから

http://download.oracle.com/javase/tutorial/java/javaOO/nested.html

InnerClassのインスタンスのみ OuterClassのインスタンス内に存在し、その 封入のメソッドとフィールドへの直接アクセスを有することができインスタンス。

この文では、次のようなアプローチが適しています。クラス名の助けを借りて解決することによって "this"を使用してインスタンスにアクセスしています。ここでは、 で定義されています。例えば

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#20860

class SecondInner extends FirstInner 
     { 

      public SecondInner(double r) 
      { 
       Outer.this.super(r);  //<------------- 
      } 

      public void showSum() 
      { 
       System.out.print("\nArea of circle = " 
        +(Math.pow(r, 2)*Math.PI)+"\n\n"); 
       } 
      } 
} 

あなたSecondInnerは、それがFirstInner.thisを使用してアクセスする必要がありますFirstInner内で宣言されるならば。スーパー()

2

私は私のEclipse環境から別のエラーを取得する:

「タイプ外のエンクロージングインスタンスが何らかの中間のコンストラクタに利用できません」

は、この1つは明確であるとにリンクさせることができます実際には、外部クラスがインスタンス化される前に非静的な内部クラスをインスタンス化することはできません。