0

我在理解 OOP、抽象类和列表的方式时遇到了一些麻烦。我目前的项目在处理中——当然只是为了原型设计。

我的问题是我有一个包含一些相同变量的对象列表。所以我为它们创建了一个抽象类,然后是所有对象的列表(抽象类作为列表),然后将变体对象添加到“抽象”列表中。

这是代码 - 整个交易可以在下面找到:

ArrayList<Vehicle> vehicles = new ArrayList<Vehicle>();

void setup() {
  vehicles.add(new Motorcycle());
  vehicles.add(new Motorcycle(2,"Yamaha"));
  vehicles.add(new Truck());
  vehicles.add(new Truck(4,"ASU AC2",2));

  print(vehicles);
  vehicles.get(3).dropLastTrailer(); 
}

卡车:

class Truck extends Vehicle {
  int numOfTrailers;

  Truck() {
    super();
    numOfTrailers = 0;
  }

  Truck(int size, String name, int numOfTrailers) {
    super(size, name);
    this.numOfTrailers = numOfTrailers;
    type = "Truck";
  }

  void dropLastTrailer() {
    numOfTrailers--;
    println("Dropped one trailer, the truck now got " + numOfTrailers + " trailers");
  }
}

车辆:

abstract class Vehicle {
  int speed, size;
  String name;
  String type;

  Vehicle() {
    this((int)random(0,6),"Unknown Vehicle");
    type = "Vehicle";
  }

  Vehicle(int size, String name) {
    this.size = size;
    this.name = name;
  }

  String toString() {
    return (name + " is " + size + "m long " + type);
  }
}

代码一直有效,直到我尝试调用“dropLastTrailer”函数,它说该方法不存在。我想这是正确的,因为它认为它只是一个车辆对象,而不是卡车。

我怎样才能解决这个问题?

完整代码可以在这里找到: https ://github.com/Jalict/processing-experiments/tree/master/oop_abstract_list

4

3 回答 3

1

您如何期望编译器知道它一个Truck? 您已申报车辆清单。想象一下,如果您使用list.get(0)而不是list.get(3)- 那么该值将是对 a 的引用Motorcycle,而不是 a Truck

您可以通过强制转换来解决此问题:

((Truck) vehicles.get(3)).dropLastTrailer();

...但此时您的代码假定列表中的对象的类型,这并不理想。您可以将此设为有条件的:

Vehicle mightBeTruck = vehicles.get(3);
if (mightBeTruck instanceof Truck) {
    Vehicle truck = (Truck) mightBeTruck;
    truck.dropLastTrailer();
}

这更安全,但从设计的角度来看仍然不是很好。不幸的是,给出的示例没有足够的上下文将其应用于现实世界的任务——有时这样的事情确实是必要的。通常有更清洁的方法,但这取决于您要实现的目标。

于 2013-10-25T11:01:15.993 回答
0

愚蠢的修复:演员

((Truck)vehicles.get(3)).dropLastTrailer(); 

但这有点危险。你怎么知道列表中的那个元素是否确实是一辆卡车?

更好的:

Vehicle v = vehicles.get(3);

if (v instanceof Truck) {
  // then we can safely cast
  ((Truck)v).dropLastTrailer(); 
}
于 2013-10-25T11:02:08.623 回答
0

ArrayList是类型的<Vehicle>并且Vehicle没有dropLastTrailer()方法。

所以首先你必须将你的对象向下转换Truck,然后你才能像这样调用这个函数。

((Truck) vehicles.get(3)).dropLastTrailer();
于 2013-10-25T11:05:45.733 回答