2014-03-30 13 views
1

好奇,爲什麼以下代碼私有變量內部類:值的解釋?

public class OuterClass{ 
    int i; 
    public void printme(){ 
    System.out.println("Outerclass"); 
    i+=20; 
    System.out.println(i); 
     class InnerClass extends OuterClass { 
      public void printme(){ 
       System.out.println("InnerClass"); 
       i+=10; 
       System.out.println(i); 
      } 
     } 

     InnerClass second = new InnerClass(); 
     second.printme();  
     System.out.println("Outerclass-2"); 
     System.out.println(i); 

     return; 
    } 

    public static void main(String []args){ 
     System.out.println("start"); 
     OuterClass first = new OuterClass(); 
     first.printme(); 

    } 


} 

輸出是

開始在OuterClass 20將InnerClass 10在OuterClass-2 20

但是,如果INT I被聲明爲private輸出是

start外部類20內部類30 Outerclass-2 30

有人能解釋一下嗎?

回答

3

當現場有沒有訪問修飾符,它有默認的知名度。

InnerClass#printme()範圍,子類的方法,它是可訪問的。所以

i+=10; 

正在訪問InnerClass實例的領域,這是初始化爲0

private字段是不是子類可見,因此InnerClass無法訪問自己的。但是因爲您的InnerClassOuterClass的內部類,它可以訪問封閉實例的字段。所以

i+=10; 

正在訪問OuterClass實例的領域。

+1

部分看here如果你給我你的地址,我會送你一個較慢的鍵盤。你似乎總是用這樣的答案來打敗我。 –

+1

@DavidWallace我住在Stackoverflow服務器的街對面。 –

3

A private字段無法在sub-class中訪問,但是可以在內部類中訪問。

所以,如果你有

int i; 

// in InnerClass extends Outerclass 
i += 10; // access the parent of this InnerClass 

然而

private int i; 

// in InnerClass extends Outerclass 
i += 10; // access the OuterClass as the parent is not accessible. 
2

肯定。如果它不是私人的,那麼它被InnerClass繼承 - 也就是i所運行的是InnerClass對象中的那個。如果它是私人的,它不能被繼承,所以操作的i是包含對象中的一個。

1

InnerClass不嚴格內部類,其通常從類主體聲明已知的。在這種情況下,它是local class,確實是一種內部類,但應用了不同的規則。這個問題都是關於繼承,因此 - 影子變量。

就你而言,如果使用default(none)修飾符擴展類,則可以訪問此字段,並且可以有效地看到超類的字段。

如果字段聲明爲private,那麼子類還看不出來,但因爲它擴展了你OutterClass所以新對象以0默認值開始它有它自己。

在文檔的約Shadowing and local classes

+0

從技術上講,它是一個內心階層。這就是爲什麼它可以訪問封閉實例的字段。 [所有本地類都是內部類(§8.1.3)。](http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.3) –

+0

@SotiriosDelimanolis你'對了 - 它被糾正了 –