你能改变一个不可变的 class 吗?

Can you change a immutable class?

这是一道实践题。

问题是

Create an immutable class Car.

Create some instances of car to fill an Arraylist<Car> inside a Garage class.

The MyGarage class implements these methods from Garage:

  • getCar(String reg) – search for the car with registration number reg.
  • getMake(String make) – returns a list of cars that match the given make.
  • totalValue() – calculates the total value of all cars in the list.
  • changeOwner(String reg, String ow) – change the owner of car that has registration number reg to ow.

我不明白 changeOwner 方法,因为它不能更改不可变的实例 class 我想???

这就是我为解决它所做的工作,但看起来很愚蠢

import java.util.ArrayList;

public class MyGarage implements Garage {
    
    private ArrayList<Car> myGarage;
    
    public MyGarage() {
        myGarage = new ArrayList<Car>();
    }

    @Override
    //Adds a Car if the registration is unique 
    public boolean add(Car c) {
        for(Car car : myGarage) {
            if(car.getRegistration().equals(c.getRegistration())) {                         
                System.out.println("Car has the same Registration as another illegal");
                return false;       
            }   
        }
        myGarage.add(new Car(c.getOwner(),c.getRegistration(),c.getMake(),c.getkilometres(), c.getprice()));
        return true;
    }

    @Override
    public Car getCar(String carID) {
        for(Car car : myGarage) {
            if(carID.equals(car.getRegistration())) {
                System.out.println("Car Found");
                return car;
            }
        }

        System.out.println("No car of that record");
        return null;
    }

    @Override
    public ArrayList<Car> getMake(String make) {
        
        ArrayList<Car> carModel = new ArrayList<Car>();
            for(Car car : myGarage) {
                if (car.getMake().equals(make)) {
                    carModel.add(car);
                }           
            }
        System.out.println(carModel.toString());        
        return carModel;
    }

    @Override
    public  void totalValue() {
        double amount = 0;
        for(Car car : myGarage) {
            amount = car.getprice() + amount;
        }
        System.out.println("The total amount is: " + amount);
    }

    @Override
    public boolean changeOwner(String registration, String ow) {

        for(Car car : myGarage) {
            if(car.getRegistration().equals(registration)) {
                myGarage.remove(car);
                car = new Car(ow, "444","F-50",  4, 4000.99);
                myGarage.add(car);
                return true;
            }
        }
        return false;
    }
}

In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created. This is in contrast to a mutable object (changeable object), which can be modified after it is created. In some cases, an object is considered immutable even if some internally used attributes change, but the object's state appears unchanging from an external point of view. - WikiPedia

因此,不可变对象是在初始化后状态不会改变的实例。这些类型的 classes 通常适用于需要实现某种形式的缓存以及您担心多线程环境中线程安全的应用程序(不可变对象本质上是线程安全的)。

我没有看到你的 Car class,但假设它看起来像这样:

public final class Car { 

  final String registration; 
  final String owner; 

  public Car(String registration, String owner) { 
    this.registration = registration; 
    this.owner= owner; 
  } 

  public String getRegistration() { 
    return registration; 
  } 

  public String getOwner() { 
    return owner; 
  } 
} 

...请注意,此 class 中没有 setter 方法。因此 car 只能被初始化(即 Car myCar = new Car("abcd", "John"); 并且其中的变量(即 registrationowner)永远无法更新。

所以你的 changeOwner 方法本质上是在你的 garage 中循环遍历 car 的实例,当它找到匹配的注册号时,它会删除 car 的那个实例来自您的 garage,然后添加一个全新的。

为了演示这一点,您可以 运行 以下内容:

public class Garage {

  public static void main(String ... args) {
    List<Car> myGarage = new ArrayList<>();
    myGarage.add(new Car("CG404GH", "John"));
    System.out.println(myGarage);
    for(Car car : myGarage) {
        if("CG404GH".equals(car.getRegistration())) {
            myGarage.remove(car);
            Car updateCar = new Car("DD404GH", "John");
            myGarage.add(updateCar);
        }
    }
    System.out.println(myGarage);
  }

}

这将打印出类似于以下的内容(@ 之后的部分在每个 运行 上都不同):

[Car@4411d970]
[Car@6442b0a6]

这里要注意的重要一点是@后面的值是不同的,因此它们是car

的两个完全不同的classes(实例)