静态方法的多态性

时间:2016-01-17 06:11:37

标签: java

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

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;
}

2 个答案:

答案 0 :(得分:1)

你是在想这个。

简而言之,这段代码正在完全你希望它做什么。

这是发生的事情。

您的父类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;
}

答案 1 :(得分:0)

您需要可重写的方法,并且您希望进行多态调度,这意味着它们不应该是静态方法。

  

但是,给定的ScreenElement是否为Landable取决于类,而不是实例。

因此,使用实例状态使方法实例方法不使用