Сеттеры и геттеры с составом в Java - PullRequest
1 голос
/ 12 апреля 2020

У меня есть сомнения относительно сеттеров и геттеров в Java, когда дело доходит до использования композиции вместо наследования. Это сомнение возникло, когда я решал задание в колледже.

Допустим, у меня есть 2 класса: автомобиль и аккумулятор. Батарея имеет 3 переменные (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;
  }

Я знаю обоснование метода геттера (так как это связано со ссылками на объект), но как насчет метода установки? Я пытался искать в Интернете вместе с Java курсом в Удеми (от Тима Бучалки), но я не видел этого адреса.

Может кто-нибудь помочь мне, пожалуйста? Спасибо!

Ответы [ 5 ]

1 голос
/ 12 апреля 2020

Каждый из трех методов в классе Car создает защитную копию из Battery. Это препятствует тому, чтобы любой другой объект за пределами Car изменил Battery, который находится внутри Car, потому что никакой другой объект не будет иметь ссылку на этот указанный c Battery экземпляр (так как он всегда копируется) .

Идиома new Battery(battery) известна как конструктор копирования , поскольку она использует конструктор для клонирования объекта. Это общий атрибут защитного копирования.

0 голосов
/ 12 апреля 2020

Когда вы создаете копию батареи и сохраняете ее, вы делаете автомобиль класса невосприимчивым к мутациям.

Мутация означает, что вы сохраняете объект батареи, заданный в качестве ввода в методе сеттера, и затем где-то вниз по линии вы вносите изменения в тот же объект батареи, а затем непреднамеренно меняете объект батареи в ранее созданном автомобильном классе. а также, что может не являться частью этого изменения, поэтому, чтобы избежать таких проблем, вы можете использовать этот подход, чтобы значение объекта батареи в автомобиле изменялось только через метод установки или через конструктор.

Надеюсь, это поможет вам понять, почему они хотят, чтобы создание дополнительного объекта в методе сеттера

0 голосов
/ 12 апреля 2020

С точки зрения способа реализации я не согласен с форматом. Лучше всего написать this.battery = battery и оставить все как есть (вместо того, чтобы создавать новый объект и назначать его переменные, как сделано в вопросе).

0 голосов
/ 12 апреля 2020

Ваш код местами выглядит странно, и я изменил его на то, что, как я ожидал, будет выглядеть:

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;
  }

В чем смысл метода сеттера? Это установить / изменить значение батареи в экземпляре автомобиля, после того, как вы уже построили автомобиль. Принимая во внимание, что вы использовали бы конструктор для установки батареи во время строительства.

0 голосов
/ 12 апреля 2020

Общее правило, когда у вас есть частные объекты (в данном случае, Батарея) в качестве атрибутов в вашем классе, это то, что вам нужны геттеры и сеттеры. Получатели и установщики должны возвращать копию закрытого объекта, чтобы вы не нарушали сокрытие информации. В противном случае вы можете сделать что-то вроде этого:

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!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...