【发布时间】:2017-08-02 16:58:19
【问题描述】:
我有以下完全抽象的场景,我正在尝试使用 OOP 概念将它们组合在一起,但我正在努力解决如何正确地做到这一点。
我有 3 种类型的汽车。这辆车只能做两件事——开车(1公里)和停车。所有汽车都可以以相同的方式驱动和停止。因此,在 OOP 世界中,我会将其表示为:
class Car{
drive(){...}
stop(){...}
}
这三种汽车是CarA、CarB和CarC,它们都是这个父类Car的子类。因此,让我们以其中一个为例,比如 CarA,它看起来像:
class CarA extends Car{}
到目前为止,一切都很好。现在这是我的任务。我在 Car 类型的数组中有大量不同类型的汽车(这是可能的,因为 Car 类是所有类型汽车的父级)。我有一个函数可以挑选出一辆随机汽车(使用一个随机生成的整数作为索引的范围内),称为 getRandomCar())。一旦我得到一辆随机的汽车,我的工作就是驾驶汽车(根据 Car 父类中定义的函数发生 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 类的方法 drive()。
现在假设其中一辆汽车(例如 CarA)的驾驶方式略有不同。因此,在 CarA 的类定义中,我将重载方法 drive()。
现在我的问题是,在上述情况下,如果我得到的随机汽车之一是 CarA 类型,那么 car.drive() 调用父方法而不是子方法。但是 CarA 的驾驶方式与其他汽车不同,这就是它有一个重载方法的原因。
所以在这种情况下,除了在调用 car.drive() 之前专门放置一个 if 条件并检查随机汽车的类型是否是 CarA 的类型(这可能很乏味)之外,有没有一种好方法可以轻松调用 CarA 自己的方法过程,如果说所有汽车都有自己的驱动方法)。在 OOP 世界中是否有这样一个场景的良好而优雅的实现?
【问题讨论】:
-
你错了,即使你的变量声明的类型只是
Car,也会调用来自CarA的重载的drive方法。但是,CarA可以根据需要使用super.drive()调用来自Car的方法 -
阅读
Dynamic Method Dispatch or Runtime Polymorphism in Java。您声称 是错误的......如果我得到的随机汽车之一是 CarA 类型,那么 car.drive() 调用父方法而不是子方法....。 -
@ArvindSasikumar 没错。如果没有,它将使重载完全无用。此外,它不仅适用于 Java,而且适用于所有 OOP 语言
-
这个场景是 OOP 世界的重点之一。您的演员 (
Car car = (Car) getRandomCar(cars)) 没有用:CarA不需要转换为Car,因为它已经是Car。您的声明then car.drive() calls the parent method不正确。最派生的方法被调用,在你的情况下是CarA。为了澄清你的想法,试着把Car做成一个接口,然后实现DefaultCar,然后导出CarA、B和C。 -
@ArvindSasikumar 这种对 Java 多态性的困惑对于开始使用 Java 的 C++ 程序员来说很常见。如果您是这样的人,那么在 Java 中
virtual是默认值。 C++ 中最接近非虚方法的是final方法,但也不一样。