组成在 Java 中的 Setter 和 getter

Setters and getters with composition in Java

我对 Java 中的 setters 和 getters 有疑问,当它开始使用组合而不是继承时。 这个疑惑是在解决大学作业的时候出现的

假设我有 2 classes:汽车和电池。电池有 3 个变量(var1、var2、var3),带有 getters 和 setters。

车class是这样的:

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),但我还没有看到这个问题。

有人可以帮帮我吗?谢谢!

当您将私有对象(在本例中为 Battery)作为 class 中的属性时,一般的经验法则是您需要 getter 和 setter。 getter 和 setter 需要 return 私有对象的副本,这样就不会违反信息隐藏。否则,您可以这样做:

Car c1 = new Car(...);
...
Battery b1 = new Battery(var1, var2, var3);
c1.setBattery(b1);  // if setBattery doesn't make a copy, 
                    // then the private variable battery in c1 
                    // is the same reference as b1

b1.changeOneOfTheValues(); // I change b1, and now my private variable 
                           // in c1 is also changed!

关于它的实现方式,我不同意这种格式。更好的做法是编写 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 方法有什么意义?它是 set/change 汽车实例中电池的价值,在你已经建造了汽车之后。而您将使用构造函数在构造期间设置电池。

当您创建电池副本并存储它时,您就可以使汽车 class 免受突变影响。

突变意味着,假设您将电池对象作为输入存储在 setter 方法中,然后在某处对同一个电池对象进行更改,那么您无意中更改了之前的电池对象created car class 也可能不是该更改的一部分,因此为避免此类问题,您可以使用此方法,以便 car 中的电池对象的值仅通过 setter 方法或通过构造函数。

我希望这能帮助您理解为什么他们想要在 setter 方法中创建额外的对象

Car class 中的三种方法中的每一种都在制作 Batterydefensive copy。这可以防止 Car 之外的任何其他对象更改 Car 内部的 Battery,因为没有其他对象会引用该特定的 Battery 实例(因为它总是被复制)。

习语 new Battery(battery) 被称为 复制构造函数 因为它利用构造函数来克隆对象。这是防御性复制的常见属性。