我正在创建一个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;
}
答案 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取决于类,而不是实例。
因此,使用实例状态使方法实例方法不使用。