2011-06-07 61 views
26

如果仍然無法在包含類之外訪問,那麼聲明Java中的私有內部類公有成員的原因是什麼?或者可以嗎?爲什麼要在Java中公開私有的內部類成員?

public class DataStructure { 
    // ... 

    private class InnerEvenIterator { 
     // ... 

     public boolean hasNext() { // Why public? 
      // ... 
     } 
    } 
} 

回答

28

如果InnerEvenIterator類沒有繼承任何類或實現任何接口,我認爲這是無稽之談,因爲沒有其他類可以訪問它的任何實例。

但是,如果它擴展或實現了任何其他非私有類或接口,這是有道理的。舉例:

interface EvenIterator { 
    public boolean hasNext(); 
} 


public class DataStructure { 
    // ... 

    private class InnerEvenIterator implements EvenIterator{ 
     // ... 

     public boolean hasNext() { // Why public? 
      // ... 
     } 
    } 

    InnerEvenIterator iterator; 

    public EvenIterator getIterator(){ 
     return iterator; 
    }  

} 
+0

所以 - 作爲一般規則 - 沒有類成員訪問修飾符可以優先於成員類的訪問修飾符。那是對的嗎? – jdurston 2014-11-28 15:26:33

8

當您實施任何interface時,它很有用。

class DataStructure implements Iterable<DataStructure> { 

    @Override 
    public Iterator<DataStructure> iterator() { 
     return new InnerEvenIterator(); 
    } 
    // ...   

    private class InnerEvenIterator implements Iterator<DataStructure> { 
     // ...  
     public boolean hasNext() { // Why public? 
      // ... 
      return false; 
     } 

     @Override 
     public DataStructure next() { 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 

     @Override 
     public void remove() { 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 
    } 

    public static void main(String[] ex) { 
     DataStructure ds = new DataStructure(); 
     Iterator<DataStructure> ids = ds.iterator(); 
     ids.hasNext(); // accessable    
    } 
} 
4

我認爲你錯過了在示例代碼中實現Iterator接口部分。在這種情況下,您不能使hasNext()方法具有除公共以外的任何其他可見性標識符,因爲這將最終降低其可見性(接口方法具有公開可見性)並且不會編譯。

3

有很多訪問修飾符的組合是沒有用的。只有在公共類/接口中實現公共方法時,私有內部類中的公共方法纔有用。

public class DataStructure { 
    // ... 

    private class InnerEvenIterator implements Iterator { 
     // ... 

     public boolean hasNext() { // Why public? 
      // ... 
     } 
    } 

    public Iterator iterator() { 
     return new InnerEvenIterator(); 
    } 
} 

BTW:抽象類往往有public構造函數時,實際上他們是protected

+2

這不是關於「有用」的;在實現一個接口時你只是沒有選擇。 :-) – 2011-06-07 11:54:50

+1

這是真的,但我的觀點是,如果您不執行或覆蓋公共方法,則該方法不需要公開,並且可以爲私人類提供私人空間。如果它不能被「public」訪問並且可能會引起誤解或混淆,那麼將其設置爲「public」是無用的。 – 2011-06-07 12:01:16

12

這種方法,以表明它是語義公衆,儘管編譯器不強制可見性規則可製成public在這個特殊情況下。

想象一下,在某些重構過程中,您需要將此內部類設置爲頂層。如果這種方法是private,你會如何決定是否應該製作public,或者應該使用一些更具限制性的修飾符?聲明方法public告訴讀者原作者的意圖 - 這種方法不應被視爲實現細節。

+4

這正是我在嵌套類中使用public和private的原因!爲什麼我們會用不同的方式使用可以從外部調用的私有方法編寫嵌套類?我通常認爲外部類不應該在內部類中調用私有方法,只有公共方法,即使編譯器不強制執行此方法。作爲獎勵,您可以稍後將嵌套類重構爲頂級類,而無需將私有方法更改爲公共。 – 2014-11-26 22:43:54

1

如果內部類是私人的,它不能通過外部類的名稱訪問。內部類和外部類可以訪問彼此的私有方法和私有實例變量。只要你在內部或外部類別中,公共和私人的修飾符都具有相同的效果。在你的代碼示例:

public class DataStructure { 
    // ... 

    private class InnerEvenIterator { 
     // ... 

     public boolean hasNext() { // Why public? 
      // ... 
     } 
    } 
} 

至於類數據結構而言,這是完全等同於:

public class DataStructure { 
    // ... 

    private class InnerEvenIterator { 
     // ... 

     private boolean hasNext() { 
      // ... 
     } 
    } 
} 

這是因爲只有數據結構可以訪問它,所以它並不重要,如果你把它設置爲公共或私人。不管怎樣,DataStructure仍然是唯一可以訪問它的類。使用你喜歡的修飾符,它沒有任何功能差異。唯一不能隨意選擇的時間是在實施或擴展時,在這種情況下,您無法減少訪問權限,但可以增加訪問權限。因此,如果抽象方法保護訪問權限,您可以將其更改爲公共。沒有一個實際上有任何區別。

如果您打算在其他類中使用內部類,並因此將其公開,您可能不應該首先將其作爲內部類。

此外,我沒有看到內部類擴展或實現其他類的任何要求。他們這樣做可能很常見,但這當然不是必需的。

+0

在這種情況下,'private'和'public'之間有一點區別:非私有方法可以被其他內部類替代,而私有方法則不能。 – 2017-06-06 12:52:49

相關問題