我的车库里真的有车吗?
我是Java编程的新手,试图掌握OOP的窍门。
所以我构建了这个抽象类:
public abstract class Vehicle{....}
和 2 个子类:
public class Car extends Vehicle{....}
public class Boat extends Vehicle{....}
Car
并且还保留了一些不常见的唯一字段和方法(没有相同的名称,因此我无法在Carue中为它们定义抽象方法)。Boat
现在在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();
所以我的问题是 - 我的车库里到底有什么?我试图获得直觉,并理解“幕后”发生的事情。
为了将来的读者,以下是答案的简短摘要:
- 是的,有一个
Car
myGarage[]
- 作为一种静态类型化语言,Java编译器不会允许访问非“Vehicle”的方法/字段,如果通过基于 Vehicle 超类的数据结构(例如
Vehicle myGarage[]
) - 至于如何解决,下面有2种主要方法:
- 使用类型转换,这将减轻编译器的担忧,并将设计中的任何错误留给运行时
- 我需要铸造的事实表明设计是有缺陷的。如果我需要访问非车辆功能,那么我不应该将汽车和船只存储在基于车辆的数据结构中。要么使所有这些功能都属于 Vehicle,要么使用更具体(派生)的基于类型的结构
- 在许多情况下,组合和/或接口将是继承的更好替代方案。可能是我下一个问题的主题...
- 再加上许多其他好的见解,如果一个人确实有时间浏览答案的话。