2016-01-17 65 views
1

我创建了一个Mario克隆,其中屏幕上的所有内容都是ScreenElement的一个实例。 A 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

为什么不制作一个'LandableElement'类继承'ScreenElement'并且被landable元素继承?然后你可以重写'Landable Element'中的方法,或者使用'instanceof LandableElement'来检查对象是否可以放置。 – Zarwan

+0

@Zar,'instanceof'可能不是最好的建议;一般或其他。 – ChiefTwoPencils

+0

@Zar在某些情况下,我有一个子类重写'isLandable'第二次将其设置为false。 – Amaar

回答

1

你正在推翻这一点。

简而言之,这段代码正在做,正好是你想要做的事情。

这是发生了什么事。

您的父级ScreenElement默认使用isLandable()方法定义,并且始终设置为返回false。通过创建一个ScreenElement的新类,如果他们希望改变这种行为,他们必须重写该方法才能这样做。

GrassBlock确实覆盖此方法表示,如果其财产isLandable()检查一个GrassBlock的任何实例将注册true的事实。


与您的代码修改,你仍然这得太多。

所有你需要做的当您尝试使用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; 
} 
+0

是的你的权利,它现在正常工作。但是,我遇到了另一个问题,这就是为什么我要提出这个问题。查看我对我的问题所做的修改。 – Amaar

+0

@Amaar:我修改了我的答案。你仍然在推翻这一点。 – Makoto

+0

所以你建议我把它作为一个实例方法,并且如果我需要弄清楚某个特定类是不是Landable的话就创建一个实例。 – Amaar

0

事实上,你需要的方法是可重写的,你想做多态调度意味着他们不应该是静态方法。

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

因此,使用实例状态,使方法实例方法没有

+0

我明白你的观点。事实上,我现在就是这样设立的。事情是,我遇到了一个案例,我有一个给定的类,并需要使用'isLandable'方法。我能做到这一点的唯一方法就是创建一个类的实例,以便能够调用这个方法,这看起来不自然。 – Amaar