你可能偶爾需要編寫退化類糯笙,目的只是為了集中實例域:
// Degenerate classes like this should not be public!
class Point {
public double x;
public double y;
}
標準寫法是:
// Encapsulation of data by accessor and mutators
class Point {
private double x;
private 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; }
}
如果一個類可以被包外訪問施流,那么就要提供訪問方法垦缅,以便可以靈活地改變類的內(nèi)部表示自赔。如果public類暴露了其數(shù)據(jù)域,則要想在將來改變內(nèi)部表示是不可能的背犯,因為他的客戶端代碼可能已經(jīng)遍布各處了坏瘩。
然而,如果類是package-private或是private嵌套類漠魏,那么把數(shù)據(jù)域暴露出去并沒有本質(zhì)的錯誤——假設(shè)這些數(shù)據(jù)域充分描述了該類提供的抽象倔矾。無論是在類定義中,還是在客戶端代碼中柱锹,這種方法相對于訪問方法更不會產(chǎn)生視覺混亂哪自。雖然客戶端代碼與類的內(nèi)部表示緊密相連,但這些代碼被限定在同一個包中禁熏。如果需要改變內(nèi)部數(shù)據(jù)表示壤巷,你不必修改包外的任何代碼。如果是private嵌套類瞧毙,則甚至不需要修改類外的任何代碼胧华。
除非修改其API,否則你不能修改其內(nèi)部數(shù)據(jù)表示宙彪,而且當別人讀取該字段時 你不能采取任何附加行動矩动,但是你可以強加約束條件(——因為只有你自己可以set該字段)
補救辦法: public域加入約束條件
// public class with exposed immutable fields - questionable
public final class Time {
private static final int HOUR_PER_DAY = 24;
private static final int MINUTES_PER_HOUR = 60;
public final int hour;
public final int minute;
public Time() {
//強加約束條件
if (hour < 0 || hour >= HOUR_PER_DAY) {
throw new IllegalArgumentException();
if (minute < 0 || minute >= MINUTES_PER_HOUR) {
throw new IllegalArgumentException();
this.hour = hour;
this.minute = minute;
}
}
Summary
public類永遠不要暴露其可變的字段。而public類暴露其不可變字段雖然是有問題释漆,但危害性要小一些悲没。然而,package-private或者private的嵌套類暴露其字段則是可行的灵汪,無論該字段是可變還是非可變檀训。