我在理解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
答案 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();