簡體   English   中英

為什么使用私有修飾符用於不可變的最終實例var?

[英]Why use private modifier for immutable final instance var?

我正在編寫一個代表一些簡單幾何的Java類。

在最頂層的abstract類(它本身就是包私有 )中,我聲明了需要從同一個包中的子類訪問的屬性。

如果我在AbstractClass聲明一個屬性為final

final int foo;

我可以直接在包中訪問它,而不用任何getter方法。 然而。 根據“praxis”(或我認為是常見的風格)做的將是:

private final int foo;

這當然需要非private吸氣劑。 子類必須引用foo (這是一個非常相關和典型的屬性),好像它是一些外部對象:

this.getFoo();

它添加了代碼並刪除了訪問這些成員的直接方式(即foo )。

跳過private修飾符是否有任何缺點,因為它們無論如何都是最終的,我不擔心在包內部暴露這些屬性?

我知道OO倡導者聲稱getter / setter是對象訪問他們自己的屬性的一種非常自然的方式 - 但是什么時候這會使任何非整形,非[插入任何JavaBeans風格的東西],差異?

考慮一個內部類Coordinate ,它非常簡單,因為它有兩個int屬性 - 留下類OuterClass所有用法:

class OuterClass{
    final static class Coordinate{
        final int x, y;
        Coordinate(int x, int y){
            this.x = x;
            this.y = y;
        }
    }
    Coordinate coordinate;
}

對於這個內部階級 - 為什么我要為創造一個吸氣劑的實踐而煩惱? getter會引入更多代碼並強制同一個包中的任何類調用coordinate.getX(); 而不是簡單的coordinate.x; 這有任何開銷嗎? 注意Coordinate類的final修飾符。

getter的優點是將接口與實現分離。 今天你的getFoo可能getFoo返回foo ,但是將來你可能想要遠程getFoo foo成員並返回計算結果。 獲取者將允許您在不需要在每個呼叫站點進行更改的情況下執行此操作。

如果你要從JSF頁面訪問這個值,它會期望getFoo而不僅僅是foo(即使你寫了object.foo )。

除此之外 - 今天這個領域是最終的,很長一段時間它可以改變(我猜)。 即使機會非常接近0,我相信在遵循良好做法方面也沒有過度殺傷力。 大多數時候你進行更改而不是從頭開始編寫代碼,因此最好盡可能保護自己(如果只需編寫private並且在eclipse的情況下大約需要4次點擊以自動生成getter和setter)。

擴展Feldgendler的答案(對於需要回答這個問題的人可能有用的信息 - 我相信這是相關的,因為它確實是一個關於封裝的問題):

在使用private修飾符時,您必須創建“getter”(例如int getX(){ ... } )以維持訪問。 哪個可以在已實現的interface聲明。 一個Java interface 不允許實例變量,如該示例的聲明final int x; ---或缺少static修飾符的任何其他變量。 該接口將充當任何實現類將具有的行為的聲明。

如果實施如下:

Coordinate implements ICoordinate { ... }

它在許多場景中都很有用:

使用界面

  • API的自我記錄。
    • 易於閱讀,記錄和管理。
    • 因此,允許容易地使用和交換多個實現。
    • 在基於組件的設計中以及更多:提供顯式方法來提供要求所描述的行為,而無需實際准備任何實現代碼。
      • 示例:然后可以創建一個提供接口的數據庫組件。 John Doe想要編寫一個將來會使用數據庫的程序。 但是現在使用其他更簡單的存儲形式就足夠了。 為了在日期到來時不重新編碼已經正在運行的代碼,John可以使用void insert( ... ); Object get( ... );方法實現一個接口(可能是名稱interface IDatabase void insert( ... ); Object get( ... ); void insert( ... ); Object get( ... ); 或許還有一些 - 然后實施他的臨時解決方案。 這一天來了,他現在有一個實現相同interface IDatabase的數據庫。 要交換到新數據庫,他可能只需要更改*一行代碼*(例如構造函數調用)!
  • 一個例子是為了它: http//pastebin.com/vvV2Nck8

使用私有修飾符

  • 澄清了課程的意圖 與界面非常相似,它具有自我記錄的性質。 (它沒有安全價值)
    • private修飾符意味着它不會超出范圍。 或者等效 - 僅在特定范圍內訪問。 同樣適用於public ,“package-private”(沒有修飾符暗示package-private)和protected
    • 訪問屬性不會明確告訴調用者它是什么類型的變量。 有一個吸氣劑,但沒有setter說了別的東西......
    • 注意:對於常量(例如static final double LIGHT_SPEED ),有合理的理由省略getter並將其public 這只是慣例,因為它將清楚什么是常量,什么是具有自己成員的對象。
    • 注2:如果感興趣,請閱讀final關鍵字及其對優化的影響。 它們既可以用於方法,也可以用於屬性。 在Java中使用final關鍵字可以提高性能嗎?就是一個例子)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM