我的车库真的有车吗?

问题:

我是Java编程的新手,试图获得OOP的悬念。
所以我建立了这个抽象类:

public abstract class Vehicle{....}

和2个子类:

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

 CarBoat还包含一些不常见的唯一字段和方法(不具有相同的名称,因此我无法为Vehicle定义抽象方法)。
现在在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();

所以我的问题是 – 我在车库里真的有什么?我正在努力获得直觉,并了解“幕后”发生了什么。
为了未来的读者,下面简要回答一下答案:

  1. 是的,myGarage[]中有Car
  2. 作为一种静态类型语言,如果通过基于Vehicle超类的数据结构(如Vehicle myGarage[])访问那些,那么Java编译器将无法访问非“Vehicle”的方法/字段。
  3. 至于如何解决,主要有两种方法:
     

    1. Use type casting, which will ease the compiler’s concerns and leave any errors in the design to run time
    2. The fact that I need casting says the design is flawed. If I need access to non-Vehicle capabilities then I shouldn’t be storing the Cars and Boats in a Vehicle based data structure. Either make all those capabilities belong to Vehicle, or use more specific (derived) type based structures
  4. 在许多情况下,组合和/或接口将是继承的更好的替代方法。可能是我的下一个问题的主题…
  5. 再加上许多其他好的见解,如果有人有时间浏览答案。

回答:

如果您需要在车库中区分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
通常,倒车是有缺陷的设计的标志:如果您需要区分其实际类型,请勿将车辆存放在一起。
注意:当然这里的设计可以轻松改进。这只是一个例子来证明点。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Do I really have a car in my garage?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

87 − = 79