我正在创建一个Mario克隆,其中屏幕上的所有内容都是ScreenElement的实例。如果ScreenElement是可以登陆的,则可以由Mario登陆。

public class ScreenElement {
    public boolean isLandable() {
        return false;
    }
}


一些类会覆盖isLandable,例如:

public class GrassBlock extends ScreenElement {
    @Override
    public boolean isLandable() {
        return true;
    }
}


不覆盖isLandable的类应该从最近的超类继承它。也就是说,我需要多态性。
现在,只要isLandable是实例方法,这一切都可以正常工作。但是,给定的ScreenElement是否为Landable取决于类,而不取决于实例。因此isLandable应该确实是静态的。但是,如果将其设为静态,则无法覆盖它或在未显式定义它的子类中继承。有没有解决此问题的简单方法。

编辑:
我确实意识到我现在设置的方式,它可以正常工作,但是我提出这个问题的原因是因为我遇到了问题。给定扩展了ScreenElement的类,我需要找出isLandable的结果。我唯一想到的是:

private <S extends ScreenElement> boolean isThisLandable(Class<S> category) {
    return category.newInstance().isLandable();
}


我必须创建一个新实例来找出不依赖于该实例的东西,这似乎是不自然的。

编辑2:这是我正在处理的特定代码。

private <S extends ScreenElement> S getGenericScreenElement(Mario mario, Class<S> category) {
    for (ScreenElement element : screenElements) {
        if (category.isInstance(element)) {
            S elementToTest = category.cast(element);
            if (elementToTest.isLandable()) {
                //return elementToTest if it matches additional criteria
            }
        }
    }
    return null;
}

最佳答案

您想得太多了。

简而言之,此代码完全按照您的意愿进行操作。

这是发生了什么。

父类ScreenElement默认情况下由isLandable()方法定义,并且始终设置为返回false。通过创建一个新的类ScreenElement,如果他们希望更改此行为,则必须重写该方法。

您的GrassBlock确实会覆盖此方法的事实表明,如果选中了GrassBlock属性,则true的任何实例都将注册isLandable()



对于您的代码修订版,您仍然没有想到。

尝试使用ScreenElement的实例时,您要做的所有事情-是ScreenElement的实例或其任何子级-只是调用该方法。

在您决定在运行期间决定对其进行检查之前,您无需关心该属性。现在,您进行检查的方式几乎没有任何意义。

举个例子:

ScreenElement vanillaElement = new ScreenElement();
GrassBlock block = new GrassBlock();

System.out.println(vanillaElement.isLandable()); // will print false
System.out.println(block.isLandable()); // will print true


更明确地说,使用示例代码,可以大大减少它。您不需要检查许多类型的语句,尤其是在强制转换时。您可以保证只使用ScreenElement,并且由于至少在isLandable()上定义了Mario,所以您永远不会遇到无法调用该方法的情况。

上面的代码将您的代码变成了这个。由于您的参数的用途在此方法中不清楚,因此我将留给您自己。

private ScreenElement getGenericScreenElement(Mario mario) {
    for (ScreenElement element : screenElements) {
        if (element.isLandable()) {
            //return element if it matches additional criteria
        }
    }
    return null;
}

10-06 01:35