java - 从父类(super class)中调用随机生成的子类的方法

标签 java oop

我有以下完全抽象的场景,我试图使用 OOP 概念将其组合在一起,但我正在努力思考如何正确地做到这一点。

我有 3 种类型的汽车。这辆车只能做 2 件事——行驶(1 公里)和 parking 。所有汽车都可以以相同的方式驾驶和 parking 。因此,在 OOP 世界中,我将其表示为如下所示:

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

这三种类型的汽车是CarA、CarB和CarC,它们都是这个父类Car的子类。那么让我们选择其中一个,比如 CarA,它看起来像这样:

class CarA extends Car{}

到目前为止,一切都很好。现在这是我的任务。我在 Car 类型数组中拥有大量不同类型的汽车(这是可能的,因为 Car 类是所有类型汽车的父级)。我有一个函数可以随机挑选一辆汽车(使用在一定范围内随机生成的整数作为索引),称为 getRandomCar())。一旦我随机获得一辆汽车,我的工作就是驾驶汽车(根据 Car 父类中定义的函数行驶 1 公里),然后 parking 。所以我做了类似的事情:

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.drive() 时,它会调用 Car 类的名为drive() 的方法。

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

现在我的问题是,在上述场景中,如果我获得的随机汽车之一是 CarA 类型,则 car.drive() 调用父方法而不是子方法。但CarA的驾驶方式与其他汽车不同,这就是它具有重载方法的原因。

所以在这种情况下,除了在调用 car.drive() 之前专门放置一个 if 条件并检查随机汽车的类型是否是 CarA 的类型之外,有没有一种好方法可以轻松调用 CarA 自己的方法(这可能是一个乏味的过程)过程,如果说所有汽车都有自己的驱动方法)。在 OOP 领域中是否有一个良好且优雅的实现这种场景的方法?

最佳答案

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

Car car = (Car) getRandomCar(cars);

car 现在是 CarA 的实例,引用类型为 Car。据编译器所知,car 是一个 Car

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

<小时/>

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

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

  2. 在您的 car 分配中,您不需要转换为 Car。由于getRandomCar()可以返回任何类型的Car,因此它的返回类型一定是Carcar 也使用 Car 类型进行声明,因此无需进行转换。

关于java - 从父类(super class)中调用随机生成的子类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45466829/

相关文章:

javascript - 我可以将 JsDoc 正确地作为工厂方法的返回值吗?

php - 访问关联 PHP 数组中的对象时性能大幅下降

java - 打嗝中的正则表达式

java - 如果第一个字符为零,如何删除第一个字符 |安卓|文本观察器

java - 扫描仪在使用 next() 或 nextFoo() 后跳过 nextLine()?

java - 如何在 recyclerView 的适配器中调用 scrollToPosition(position)?

java - Spring 集成: Exception Handling on Publish/Subscribe Channels with Ordered Subscribers

php - 在 OOP 中应该避免并尽可能多地使用在方法中传递参数吗?

javascript - prototype.constructor 和 object of itself 有什么区别?

c# - 如何根据基类比较两个对象?