我对使用合成而不是继承时在Java中的setter和getter有疑问。当我解决大学任务时,这个疑问就来了。
假设我有两个班级:汽车和电池。电池具有3个具有getter和setter的变量(var1,var2,var3)。
汽车课是这样的:
public class Car {
private String color;
private String model;
private Battery battery;
public Car(String color, String model, Battery battery) {
this.color = color;
this.model = model;
this.Battery = new Battery(battery);
}
public getBattery() {
return new Battery(battery);
}
public void setBattery(Battery battery) {
this.battery = new Battery(battery.getVar1(), battery.getVar2(), battery.getVar3());
//or this.battery = battery;
}
我知道getter方法的理由(因为它与对象的引用有关),但是setter方法呢?我曾尝试在网上与Udemy的Java课程一起学习(来自Tim Buchalka),但我还没有看到解决的方法。
有人可以帮我吗?谢谢!
就其实施方式而言,我不同意这种格式。更好的做法是编写this.battery = battery并将其留在该位置(而不是像问题中那样创建新对象并分配其变量)。
您的代码在某些地方看起来很奇怪,我将其更改为我希望的样子:
public class Car {
private String color;
private String model;
private Battery battery;
public Car(String color, String model, Battery battery) {
this.color = color;
this.model = model;
//Now, we're setting Car.battery to the battery that you passed in.
//Previously, you were passing the battery instance back into the Battery constructor.
this.battery = battery;
//this.battery = new Battery(battery);
}
public getBattery() {
//We want to return the battery we have above, not a new battery
return battery;
//return new Battery(battery);
}
public void setBattery(Battery battery) {
//You wouldn't do this. Just use the line you've commented out.
//No need to remake a new Battery object when you already have one passed in.
this.battery = new Battery(battery.getVar1(), battery.getVar2(), battery.getVar3());
//or this.battery = battery;
}
setter方法的重点是什么?在您构造完汽车之后,它可以设置/更改汽车实例中的电池值。而您将在构造期间使用构造函数来设置电池。
当您创建电池副本并存储时,您正在使汽车类免于突变。
突变意味着,假设您将以输入方式提供的电池对象存储在setter方法中,然后在一行中的某个位置对同一电池对象进行了更改,然后您无意中更改了先前创建的汽车类中的电池对象,这可能不应将其作为更改的一部分,因此,为了避免此类问题,可以使用此方法,以便仅通过setter方法或通过构造函数更改汽车中电池对象的值。
我希望这可以帮助您理解为什么他们想要用setter方法创建额外的对象
Car
类中的三种方法中的每一种都使defensive copy为Battery
。这样可以防止Car
之外的任何其他对象更改Battery
内部的Car
,因为没有其他对象可以引用该特定的Battery
实例(因为它总是被复制)。
成语new Battery(battery)
被称为复制构造函数
当您将私有对象(在这种情况下为Battery)作为类的属性时,通常的经验法则是,您需要使用getter和setter。获取器和设置器需要返回私有对象的副本,以便您不会违反信息隐藏的规定。否则,您可以执行以下操作: