学习接口和层次结构,在哪里放置某些变量和方法?

Learning interfaces and hierarchies, where to place certain variables and methods?

因此,作为汽车租赁系统的一部分,我需要编写 classes 来表示大型和小型汽车,它们之间的区别在于它们具有不同大小的油箱并且以不同的速率消耗燃料。目前我的方法是有一个接口 Car,由一个抽象 class AbstractCar 实现,它由两个具体的 classes SmallCar 和 LargeCar 扩展。然而,这是我第一次使用接口和抽象 classes(我们只是在 class 中介绍它们,这个作业旨在评估我们对它们的了解),我不知道该放什么在什么class。

fill方法的实现完全一样,只需要引用FUEL_CAPACITY的正确值,所以感觉应该在AbstractCarclass中实现这些方法,但是那么我不知道如何让他们引用正确的 FUEL_CAPACITY 值。字段 fuelLevel 显然也由所有汽车持有,所以我觉得我应该在 AbstractCar 中声明它,但是如果不删除它的隐私,我就无法从 subclasses 访问它。

谁能帮我弄清楚我做错了什么或对接口和继承有什么误解?我一直在考虑的一件事是生成一个枚举 CarType,让 AbstractCar 将 CarType 作为一个字段,所有实现都在 AbstractCar class 中完成,使用 if 语句切换到正确的 FUEL_CAPACITY 值,并且简单地使用 SmallCar 和 LargeCar 作为构造函数或工厂 classes,没有太多甚至没有任何实际实现。

提前感谢您提供的任何帮助,我意识到它有点啰嗦,但是我试图确保我完全理解我们正在学习的概念并且我正在正确地实施它们,而不是仅仅把一些东西搞砸'works' 但不一定是正确或最优雅的解决方案。

您可以使用您指出的值将逻辑传输到 AbstractCar。然后只需在 SmallCar 和 LargeCar 的构造函数中设置这些值。这将是一种方法。正如您所指出的,您始终必须在父 class 中拥有通用逻辑。你想避免重复的代码。然后你只需要确保在构造函数中设置不同的值。如果您知道固定值(就像您从给定的示例中所做的那样),您甚至可以省略为 SmallCar 或 LargeCar 构造函数提供参数,而只需在构造函数内的 super() 调用中设置这些固定值。

这是我的解决方案的实现。

接口 Car,我删除了 getFuelMethod() 方法,因为必须保护访问级别:

public interface Car {

  RegistrationNumber getRegistration();

  int getFuelCapacity();

  // int getFuelLevel(); this can not be implemented
  // all methods in an interface are PUBLIC
  // so you have to lower the access level by removing it from the interface

  // HERE goes the rest of the method signatures

}

}

摘要classAbstractCar:

public abstract class AbstractCar implements Car {
  // this is the common variable
  // that is why we save it in the parent class
  private int fuelCapacity;

  private int fuelLevel;

  // we forward the value to the parent constructor with the super call
  public AbstractCar(int fuelCapacity) {
    this.fuelCapacity = fuelCapacity;
    // I set the value to 0 for the start, but
    // you can also pass the value to the super call,
    // same as fuelCapacity - it is up to you
    this.fuelLevel = 0;
  }

  // The getters and setter allow us to retrieve the values
  // from the abstract class through capsulation!

  // here we have the getter to be able to retrieve the value from SmallCar and LargeCar
  public int getFuelCapacity() {
    return.fuelCapacity;
  }

  public void setFuelCapacity(int fuelCapacity) {
    this.fuelCapacity = fuelCapacity;
  }

  protected int getFuelLevel() {
    return fuelLevel;
  }

  protected void setFuelLevel(int fuelLevel) {
    this.fuelLevel = fuelLevel;
  }

  // HERE goes the rest of the code

}

这里是 SmallCar 实现:

public class SmallCar extends AbstractCar {

  private static final int FUEL_CAPACITY = 45;

  public SmallCar() {
    // we set the value in the parent class
    super(FUEL_CAPACITY);
  }

  public int drive() {
    // HERE goes the logic for drive for SmallCar. Same method is needed
    // in the LargeCar class, because the logic differes.
  }

  // HERE goes the rest of the code

}

如果你的Capacity只是Car的一个属性(只有数据),使用,但是如果计算容量可能有一些逻辑,使用这个:

最好的方法是使用抽象方法。你在你的摘要 class

中放置了一个 abstract Integer getCapacity(); 的方法
public abstract class AbstractCar implements Car {

    private final RegistrationNumber registration;
    private boolean isRented;

    AbstractCar() {
        this.registration = RegistrationNumber.getInstance();
    }

    public RegistrationNumber getRegistration() {
        return registration;
    }

    public boolean isRented() {
        return isRented;
    }

    //You can use this method in other methods of AbstractCar, but is implemented in your concrete classes
    public abstract Integer getCapacity();

    public boolean isFull() {
        if (fuelLevel == getCapacity()) {
            return true;
        } else return false;
    }


}

然后在其他功能中使用它。在你的具体 class 中,你定义了方法的主体:

public Integer getCapacity(){
    //Your logic to calculate capacity for every concrete class here
}

如果您只想对 class 用户隐藏 FUEL_CAPACITY 而不是对其他开发人员隐藏,您可以在 AbstractCar[ 中将其声明为 protected =18=] 并在子 classes 中用适当的值初始化它。另外我会在AbstractCar中声明一个getter方法getCapacity(),其中returns这个值。