从其超类中调用随机生成的子类的方法

时间:2017-08-02 16:58:19

标签: java oop

我有以下完全抽象的场景,我试图使用OOP概念,但我正在努力解决如何做到这一点。

我有3种类型的汽车。这辆车只能做两件事 - 开车(1公里)然后停下来。所有汽车都可以以相同的方式驱动和停止。因此,在OOP世界中,我将其表示为如此:

class Car{
    drive(){...}
    stop(){...}
}

这三种类型的汽车是CarA,CarB和CarC,它们都是这个父级Car的子类。所以,让我们选择其中一个,CarA说,这看起来像是:

class CarA extends Car{}

到目前为止,这么好。现在,这是我的任务。我在汽车类型的阵列中有大量不同类型的汽车(这是可能的,因为汽车类是所有类型汽车的父母)。我有一个函数可以选择一个随机的汽车(使用一个在作为索引的范围内随机生成的整数),称为getRandomCar())。一旦我得到一辆随机汽车,我的工作就是驾驶汽车(根据汽车母班中定义的功能发生1公里),然后停车。所以我做了类似的事情:

Car car = (Car) getRandomCar(cars); //cars is the Car array with all the different cars
car.drive(); //car is driven for 1 km
car.stop(); //car is stopped.

这是有效的,因为我得到的随机车在将其存储到名为car的Car引用变量之前总是被类型转换为其父类。当我打电话给car.drive()时,它会调用Car class'方法叫做drive()。

现在假设其中一辆汽车,比如CarA,驾驶方式略有不同。因此,在CarA的类定义中,我将重载方法drive()。

现在我的问题是,在上面的场景中,如果我得到的随机车之一是CarA类型,那么car.drive()调用父方法而不是子方法。但是驾驶CarA的方式与其他车型不同,这就是为什么它有一个超负荷的方法。

所以在这种情况下,有一种很好的方法可以轻松调用CarA自己的方法,而不是在调用car.drive()之前专门设置if条件并检查随机车的类型是否为CarA(这可能是一个单调乏味的过程,如果所有汽车都有自己的驱动方法)。在OOP世界中是否有这种情景的良好和优雅的实现?

1 个答案:

答案 0 :(得分:1)

在Java中,方法在编译时检查,但在运行时绑定。当您将car变量声明为

Car car = (Car) getRandomCar(cars);

car现在是CarA的实例,其引用类型为Car。就编译器而言,carCar

当您调用car.drive()时,编译器会根据Car类的定义检查该方法。 Car确实包含一个名为drive()的方法,因此编译成功。当程序实际运行时,JVM会到达该语句并在实际对象上调用drive() 。由于car实际上是CarA,因此CarA的{​​{1}}版本被调用。对于drive()CarB,其中不包含自己的定义,CarC的{​​{1}}版本会自动继承。

其他一些注释(我注意到的事情和评论中提到的事情):

  1. 您在此处描述的方案称为覆盖,而不是重载。重载使多个方法具有相同的名称和返回类型,但参数不同。覆盖是通过在子类中创建相同的方法来替换超类的功能。

  2. Car作业中,您无需投放到drive()。由于car可以返回任何类型的Car,因此它的返回类型必须为getRandomCar()Car也声明为Car类型,因此无需投射。