[英]Getter for private member object in Java
说我有一个叫做Truck
的类,私有成员变量之一是Wheel
类。 Wheel
变量getWheel
getter将返回对其的引用,如下所示:
class Truck{
private Wheel wheel;
Truck(){
wheel=new Wheel();
}
Wheel getWheel(){
return this.wheel;
}
}
class Wheel{
int color;
}
现在,调用getWheel
任何人都可以随意修改私有成员对象:
class me{
public static void main(String[] args){
Truck ye=new Truck();
Wheel v=ye.getWheel();
v.color=2;
}
}
这会破坏封装,不是吗?
什么是正确的补救办法?
通常的方法是:
Wheel
的副本 ) Wheel
不可变(任何时候要更改它,都可以创建一个新的,并以新的颜色构造) Wheel
,返回一个不可变的接口Wheel
,只有公开干将,没有变异操作 public
的吸气剂。 然后,包装内的类可以设置Wheel
的颜色,但是包装外的类不能设置。 (在这种情况下,我更倾向于使用#3来实现清晰的分隔,但是如果您越过可见性边界,也可以这样做。) 第三种选择是为什么通常将实例变量(字段)设为非private
的原因之一。
这里的#3更深入,只是因为它比#1和#2更复杂,而不是因为它必须更好(不是,设计选择是在上下文中做出的)。
只读接口,通常为public或package-private,具体取决于您将如何使用所有这些东西:
public interface Wheel {
int getColor();
}
具体的类,通常是package-private(如果是在Truck
上使用的唯一位置,则可以是Truck
的私有静态嵌套类):
class WheelImplementation implements Wheel {
private int color;
WheelImplementation(int color) {
this.color = color;
}
public int getColor() {
return this.color;
}
void setColor(int color) {
this.color = color;
}
}
Truck
,通常与Wheel
相同的能见度:
public class Truck {
private WheelImplementation wheel;
Truck(){
this.wheel = new WheelImplementation(/*...initial color...*/);
}
Wheel getWheel() {
return this.wheel;
}
}
当然,可以通过反射来克服它,但是通常您设计的API是使用而不是滥用。 :-)
您可以为车轮颜色设置专用/打包设置器。 另外,在构造函数中初始化颜色,这将帮助您实现这一目标。
与其他答案一样,返回Wheel的副本也是执行此操作的好方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.