在抽象类列表中的类上调用函数

时间:2013-10-25 10:58:19

标签: java arrays list oop abstract

我在理解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

3 个答案:

答案 0 :(得分:1)

您希望编译器知道 Truck吗?你已经宣布了一份车辆清单。想象一下,如果您使用list.get(0)而不是list.get(3) - 那么该值将是对Motorcycle的引用,而不是Truck

你可以通过施放来解决这个问题:

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

...但是在那时你的代码是假设列表中对象的类型,这是不理想的。你可以使这个有条件:

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

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

答案 1 :(得分:0)

哑修复:施放

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

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

更好:

Vehicle v = vehicles.get(3);

if (v instanceof Truck) {
  // then we can safely cast
  ((Truck)v).dropLastTrailer(); 
}

答案 2 :(得分:0)

您的ArrayList类型为<Vehicle>Vehicle没有dropLastTrailer()方法。

首先,您必须将对象转发为Truck,然后才能调用此函数。

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