在公有類中使用訪問方法而非公有域

class Point {
  public double x;
  public double y;
}

這種類數據是可以被直接訪問的,這些類沒有提供封裝的功能,如果不改變API,就無法改變它的數據表示法,也無法強加任何約束條件,當域被訪問的時候,無法采取任何輔助的行動,堅持面向對象程序設計的程序員對這種類深惡痛絕,認為應該用包含私有域和公有訪問方法來代替。對于可變的類來說,應該用包含私有域和公有設值方法的類來代替,就是我們所說的 get和set方法。

class Point {
    public double x;
    public double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    public void setX(double x) {
        this.x = x;
    }

    public void setY(double y) {
        this.y = y;
    }
}

毫無疑問,說到公有類的時候,堅持面向對象程序設計思想的看法是正確的,如果類可以在它所在的包的外部進行訪問,就提供訪問方法。以保留將來改變該類的內部表示方法的靈活性,如果公有類暴露了他的數據域,要想在將來改變其內部表示法是不可能的,因為公有類的客戶端代碼已經遍布各處了。
然而,如果類是包級私有的,或者是私有的嵌套類,直接暴露它的數據域并沒有本質的錯誤——假設這些數據域確實描述了該類所提供的抽象。這種方法比訪問方法的做法更不會產生視覺混淆。

讓公有類直接暴露域從來都不是種好辦法,但是如果域是不可改變的,這種做法危害較小,如果不改變類的API,就無法改變這種類的表示法,當域被讀取的時候,你就無法采取輔助行動,但是可以強加約束條件。


public final class Time{
    private static final int HOURS_PER_DAY=24;
    private static final int MINUTES_PER_HOUR=60;

    public final int hour;
    public final int minute;

    public Time(int hour,int minute){
        if(hour < 0|| hour >= HOURS_PER_DAY){
            System.err.println("Error");
        }
        if(minute < 0|| minute >= MINUTES_PER_HOUR){
            System.err.println("Error");}
        this.hour = hour;
        this.minute = minute;
    }
}

總之,公有類永遠都不應該暴露可變的域。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容