又是很简单的一节
public类不应该有public属性,必须使用访问方法(accessor methods)
m88体育 有些情况下,会需要写一些纯粹用作数据存储,而没有任何行为的类,比如:
// Degenerate classes like this should not be public! class Point { public double x; public double y; }
按上一节所说,这样做会破坏数据封装,所以Object-Oriented语言的死忠分子们会拒绝接受这样的写法,并要求全面使用访问方法改写它:
// Encapsulation of data by accessor methods 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; } }
这样的改写对于public类是必要的:如果一个类在它所在的包以外是可见的,那么它必须提供访问方法,而不能开放数据属性为public。但如果类是仅包内可见(package-private),那么这样的数m88体育 据开放却并没有太严重的后果。对于私有内嵌类,危害会更小。事实上,对于非public类,开放数据属性的确会使数据存取依赖于类的内部实现,但同时使代码更清楚易读。
虽然public类开放数据属性危害明显,但如果被开放的属性是immutable,那么其危害就大大减小。比如下面的代码,不会面临特别严重的问题:
// Public class with exposed immutable fields - questionable 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) throw new IllegalArgumentException("Hour: " + hour); if (minute < 0 || minute >= MINUTES_PER_HOUR) throw new IllegalArgumentException("Min: " + minute); this.hour = hour; this.minute = minute; } ... // Remainder omitted }