第14条:在公有类中使用访问方法而非公有域
有时候、可能会编写一些退化类(degenerate classes),没有什么作用,只是用来集中实例域:
class Point {
public double x;
public double y;
}
由于这种类的数据是可以直接被访问的,这些类没有提供封装(encapsulation)的功能。如果不改变API,就无法改变它的数据表示法,也无法强加任何约束条件,当域被访问时,也无法采取任何辅助的行动。对于这种可变的类来说,应该用包含私有域和公有设值方法(setter)的类来代替:
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 void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
}
毫无疑问,说到公有类的时候,坚持面向对象程序设计思想的看法是正确的:如果类可以在它所在的包的外部进行访问,就提供访问方法,以保留将来改变该类的内部表示法的灵活性。如果类暴露了它的数据域,要想将来改变其内部表示法是不可能的,因为公有类的客户端代码已经遍布各处了。
然而,如果类是包级私有的,或者是私有的嵌套类,直接暴露它的数据域并没有本质的错误–假设这些数据域确实描述了该类提供的抽象。虽然客户端代码与该类的内部表示法紧密相连,但是这些代码被限定在包含该类的包中,如果有必要,不改变包之外的任何代码而只改变内部数据表示法也是可以的。在私有嵌套类的情况下,改变的作用范围被进一步限制在外围类中。
让公有类暴露域不是好办法,但如果域是不可变的,这种做法的危害会较小:
public final class Time {
private static final int HOURS_PER_DAY = 24;
private static final int MINUTES_PER_HOURS = 60;
public final int hour;
public final int minute;
public Time(int hour, int minute) {
if(hour < 0 || hour > HOURS_PER_DAY)
throw new IllegalArgumentException("Hour: " + hour);
if(minute < 0 || minute >= MINUTES_PER_HOUR)
throw new IllIllegalArgumentException("Minute: " + minute);
this.hour = hour;
this.minute = minte;
}
}
总之,公有类永远都不应该暴露在可变的域。虽然还是有问题,但是让公有类暴露不可变域其危害比较小。但是,有时候会需要包级私有的或者私有的嵌套类来暴露域,无论这个类是可变的还是不可变的。
第14条:在公有类中使用访问方法而非公有域&spm=1001.2101.3001.5002&articleId=90797239&d=1&t=3&u=e1cff20050f14bfba545409543989cbb)
1468

被折叠的 条评论
为什么被折叠?



