如何在 Java 中调用类共享的方法而不首先抛出 Object 超类

How do I call a method shared by classes without casting out of the Object superclass first in Java

提问人:A Person 提问时间:10/21/2022 更新时间:10/21/2022 访问量:49

问:

我有多个不同的类(,,),每个类都有不同的绘制方法,我希望能够通过一次调用调用它们各自的方法,而不必对它们进行 3 次不同的强制转换。StarPlanetMoondraw()

Object solarObject = solarObjects.get(i);

if (solarObject.getClass() == Star.class)   ((Star)   solarObject).draw(system);
if (solarObject.getClass() == Planet.class) ((Planet) solarObject).draw(system);
if (solarObject.getClass() == Moon.class)   ((Moon)   solarObject).draw(system);

我想做的是这个

Object solarObject = solarObjects.get(i);

solarObject.draw(system);

我所做的另一个尝试是这样的

solarObject.getClass().cast(solarObject).draw(system);

但它给出了错误The method draw is undefined for the type


有什么方法可以在 Java 中实现这种行为吗?

Java 对象 转换

评论

6赞 Jon Skeet 10/21/2022
是的,你可以使它们都成为公共超类的子类,或者实现相同的接口。(在这种情况下,很难说哪个更合适。基本上,我建议你阅读继承和接口。
1赞 Michael 10/21/2022
solarObject.getClass() == Star.class你知道instanceof运算符,对吧? ?它并不完全相同,但就您的目的而言,几乎可以肯定完成相同的任务。好处是 solarObject 为 null 时不抛出,表现力更强。solarObject instanceof Star

答:

2赞 Ahmad Mtera 10/21/2022 #1

要通过整洁的类型转换完成相同的工作,您可以使这些类成为公共抽象/具体超类的子类,或者让它们实现一个通用接口(以适合您的项目设计为准)。这样,您可以将任何子类对象存储到该接口并在其上调用“draw()”方法(无论对象的类型如何,因为它们都实现了相同的接口)。

法典:

public interface CelestialBody {
    void draw();
}

public class Star implements CelestialBody{
    public void draw(){}
}

public class Planet implements CelestialBody{
    public void draw(){}
}

演示:

public class Driver {
    public static void main(String[] args) {
        CelestialBody solarObject1 = new Star();
        CelestialBody solarObject2 = new Planet();
        if (solarObject1 instanceof CelestialBody)
            solarObject1.draw();
        if (solarObject2 instanceof CelestialBody)
            solarObject2.draw();
    }
}

请注意,当接受未知对象时,我们在引用它之前使用“instanceof”运算符(这是为了确保输入的对象实际上是“CelestialBody”类型)。

这类问题可以通过继承来解决。我鼓励你阅读更多关于它的信息。

评论

1赞 Michael 10/21/2022
值得注意的是,使用 instanceof 模式匹配 (Java 16+),您可以避免显式强制转换为 CelestialBody: openjdk.org/jeps/394
0赞 A Person 10/21/2022
谢谢!如果我不想在实现它的类之一中实现其中一个接口方法,该怎么办?
0赞 Ahmad Mtera 10/21/2022
@APerson 您有两种选择:要么将未实现所有接口方法的子类抽象化。或者,您将 CelestialBody 设置为抽象类而不是接口(其中的“draw()”方法也必须是抽象的)。这样,任何实现“draw()”方法的子类都是具体的,而任何不需要的子类都必须是抽象的。