您可以更改一个不变的类吗?

时间:2019-11-11 00:35:30

标签: java oop arraylist immutability

这是实践的理论问题。

问题是

  

创建一个不变的类Car

     

创建一些汽车实例来填充Arraylist<Car>类中的Garage

     

MyGarage类从Garage实现以下方法:

     
      
  • getCar(String reg) –搜索注册号为reg的汽车。
  •   
  • getMake(String make) –返回与给定make匹配的汽车列表。
  •   
  • totalValue() –计算列表中所有汽车的总价值。
  •   
  • changeOwner(String reg, String ow) –将注册号为reg的汽车的所有者更改为ow
  •   

我不了解changeOwner方法,因为它不能更改我认为的不可变类的实例?

这是我为解决此问题所做的工作,但看起来很愚蠢

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 ammount = 0;
        for(Car car : myGarage) {
            ammount = car.getprice() + ammount;
        }
        System.out.println("The total ammount is: " + ammount);
    }

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

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

1 个答案:

答案 0 :(得分:0)

  

在面向对象的函数式编程中,不可变的对象   (不可更改的对象)是状态无法修改的对象   创建之后。这与可变对象相反   (可变对象),创建后即可对其进行修改。在   在某些情况下,即使在内部某些对象也被认为是不可变的   使用的属性发生变化,但是对象的状态似乎与   外部的观点。 -WikiPedia

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

我看不到您的Car类,但是假设它看起来像这样:

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

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

因此,您的changeOwner方法实际上是遍历cargarage的实例,当找到匹配的注册号时,它会将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的两个完全不同的类(实例)