gpt4 book ai didi

java - 我的车库里真的有车吗?

转载 作者:bug小助手 更新时间:2023-10-28 10:39:31 24 4
gpt4 key购买 nike

我是 Java 编程的新手,正在尝试掌握 OOP。

所以我建立了这个抽象类:

public abstract class Vehicle{....}

和 2 个子类:

public class Car extends Vehicle{....}
public class Boat extends Vehicle{....}

CarBoat 还包含一些不常见的独特字段和方法(名称不同,所以我无法定义抽象方法为他们在车辆中)。

现在我在 mainClass 中设置了我的新车库:

Vehicle[] myGarage= new Vehicle[10];
myGarage[0]=new Car(2,true);
myGarage[1]=new Boat(4,600);

在我尝试访问 Car 独有的字段之一之前,我对多态性非常满意,例如:

boolean carIsAutomatic = myGarage[0].auto;

编译器不接受。我使用强制转换解决了这个问题:

boolean carIsAutomatic = ((Car)myGarage[0]).auto;

这行得通……但它对方法没有帮助,只是对字段有帮助。意思是我做不到

(Car)myGarage[0].doSomeCarStuff();

所以我的问题是 - 我的车库里到底有什么?我正在尝试获得直觉并了解“幕后”发生的事情。


为了 future 的读者,以下答案的简短摘要:

  1. 是的,myGarage[]
  2. 中有一个 Car
  3. 作为一种静态类型语言,如果通过基于 Vehicle 父类(super class)的数据结构(例如 Vehicle myGarage[ ])
  4. 至于如何解决,主要有以下两种方法:
    1. 使用类型转换,这将减轻编译器的顾虑,并将设计中的任何错误留给运行时
    2. 我需要选角这一事实表明设计存在缺陷。如果我需要访问非车辆功能,那么我不应该将 Cars 和 Boats 存储在基于 Vehicle 的数据结构中。要么让所有这些功能都属于 Vehicle,要么使用更具体(派生)的基于类型的结构
  5. 在许多情况下,组合和/或接口(interface)是继承的更好替代方案。可能是我下一个问题的主题......
  6. 如果您确实有时间浏览答案,那么还有许多其他好的见解。

最佳答案

如果您需要区分车库中的 CarBoat,那么您应该将它们存放在不同的结构中。

例如:

public class Garage {
private List<Car> cars;
private List<Boat> boats;
}

然后您可以定义特定于船只或特定于汽车的方法。

那为什么会有多态呢?

假设 Vehicle 是这样的:

public abstract class Vehicle {
protected int price;
public getPrice() { return price; }
public abstract int getPriceAfterYears(int years);
}

每一个Vehicle都有一个价格,所以它可以放在Vehicle抽象类中。

然而,确定 n 年后价格的公式取决于车辆,所以它留给实现类来定义它。例如:

public Car extends Vehicle {
// car specific
private boolean automatic;
@Override
public getPriceAfterYears(int years) {
// losing 1000$ every year
return Math.max(0, this.price - (years * 1000));
}
}

Boat 类可能有 getPriceAfterYears 的其他定义以及特定的属性和方法。

所以现在回到 Garage 类,你可以定义:

// car specific
public int numberOfAutomaticCars() {
int s = 0;
for(Car car : cars) {
if(car.isAutomatic()) {
s++;
}
}
return s;
}
public List<Vehicle> getVehicles() {
List<Vehicle> v = new ArrayList<>(); // init with sum
v.addAll(cars);
v.addAll(boats);
return v;
}
// all vehicles method
public getAveragePriceAfterYears(int years) {
List<Vehicle> vehicules = getVehicles();
int s = 0;
for(Vehicle v : vehicules) {
// call the implementation of the actual type!
s += v.getPriceAfterYears(years);
}
return s / vehicules.size();
}

多态性的意义在于能够在 Vehicle 上调用 getPriceAfterYears,而无需关心实现。

通常,向下转型是设计有缺陷的标志:如果您需要区分它们的实际类型,请不要将车辆全部存放在一起。

注意:当然这里的设计可以很容易地改进。只是举例说明要点。

关于java - 我的车库里真的有车吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24883075/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com