好的,这是一个很难表达的问题,但这是我能想到的最好的问题。
基本上,我有一个动物类,一个昆虫类,一个继承自动物类的昆虫类,以及一个蜘蛛、木虱和蠕虫类,它们从昆虫类继承而来。
例如,我有一个名为InsectStorage的类,它在数组中定义并存储了许多昆虫对象(例如,由不同种类的蠕虫、木屋等组成的数组)。我希望用户能够选择一种昆虫,并在这个类中为玩家指定一种昆虫。
设置昆虫是可以达到的
Spider blackWidow = new Spider()
Spider wolfSpider = new Spider()
Spider[] spiderStorage = new Spider[2]
worm lumbricusTerrestris = new Worm()
...
switch (insectSelect)
case: "Black Widow"因此,开关语句是第一个复杂的地方,但是几乎可以通过创建一个类型为selectedPlayerInsect的蠕虫、蜘蛛和伍兹来解决,并根据选择设置每一个。
但是,我怎么可能创建一个getPlayerInsect()方法呢?如果选择蜘蛛,我需要能够返回蜘蛛,如果选择了蠕虫,我需要返回蠕虫。
我可以尝试为每个虫子类创建一个playerObject,并创建四个getPlayerXX()方法,但这意味着每当我想在主方法中调用getPlayerSpider()或getPlayerWorm()时,我都必须放入if语句来检查选择了哪个对象(这将非常不方便)。
我试着摆弄包装类,但也无法让这些类发挥作用(如果playerIsWorm等的话,我仍然会使用)。
大量的文字,不多的代码,但我认为代码并不是真正需要我的解释。我如何(如果我能)解决这个问题?
发布于 2014-08-13 00:13:03
所以,立即解决你的问题的方法是做类型检查-基本上是你说的。它是丑陋的,但根据你的想法,它是可行的。
然而,我认为还有一个更深层次的问题需要考虑。
如果你正确地设计你的类,昆虫类的实际“类型”应该无关紧要。您应该将不同的逻辑构建到子类中。这使得将来更容易建立在顶层上。@PM 77-1说得最好--你需要以它应该使用的方式使用多态性。
所以,相反,只需:
public Insect getPlayerInsect(){
return playerInsect;
}也许您的主要方法如下所示:
Insect player = getPlayerInsect();
player.eat(); // Everything eats您不需要(不应该)将复杂的if/ eat逻辑构建到eat语句中。
abstract class Insect {
abstract void eat();
}
class Spider extends Insect{
@Override
public void eat(){
//eat dung
}
}
class Worm extends Insect {
@Override
public void eat(){
//eat soil
}
}您将决策推迟到最后-直到方法实际被调用。这样,您就可以重用功能,并且不需要编写许多复杂的if/else语句。
如果您需要向您的昆虫播放器对象添加其他功能,只需添加它们并适当地覆盖它们。
如果您发现eat并不适用于所有子类,那么这通常意味着您需要对类层次结构进行重新建模。
发布于 2014-08-12 23:57:43
您可以将Clases/Enum用于不同类型的昆虫。
Enum Spiders {BLACKWIDOW, WOLFSPIDER};
Spider firstSpider = Spiders.BLACKWIDOW;
if (firstSpider == Spiders.BLACKWIDOW) ...与
class BlackWidow extends Spider {... }
class WolfSpider extends Spider { ... }
Spider firstSpider = new BlackWidow();
if (firstSpider instanceof BlackWidow) ....在这种情况下,您将使用instanceof或.class (用于类案例)或== (用于Enum情况)进行测试。在您的情况下,当您有一个类Spider时,您应该给它一个具有名称的属性:
Spider blackWidow = new Spider("BlackWidow");
if (blackWidow.isType("BlackWidow)) ...可以使用==操作符检查已知的实例。但是,对于实际的域分类来说,这是一种不好的做法,很难调试(并且不适用于持久化标识):
public class Spiders {
final Spider BLACKWIDOW = new Spider();
final Spider WOLFSPIDER = new Spider();
void doSpiderThing(Spider userSelection) {
if (userSelection == BLACKWIDOW) {
...
void selectSpiderByName(String spiderName) {
if ("Tekla".equals(spiderName))
doSpiderThing(BLACKWIDOW);
...或者类似的。您在备注中询问了如何返回蜘蛛或工作,您可以通过返回这两种类型的超级类型(默认情况下是对象,但更好的方法是特定的)来实现这一点:
interface Animal {String getSpecies(); }
Enum AnimalEnum implements Animal {
BLACKWIDOW { getSpecies() {return "Spider"; }},
WOLFSPIDER { getSpecies() {return "Spider"; }},
WORM { getSpecies() {return "Worm"; }}
}
Animal getAnimalBySelection(String input) {
if ("worm".equalsIgnoreCase(input))
return AnimalEnum.WORM;
else ...
}发布于 2014-08-13 00:04:23
我不确定您是否希望“播放器”能够选择昆虫对象的类型(木虱、蠕虫、蜘蛛)或昆虫‘名称’的类型(因为没有更好的术语-- Blackwidow、Wolf蜘蛛等等)。
如果是前者,在为播放器创建新的昆虫时,似乎可以使用getClass()方法(getclass.htm),并将其与枚举列表中的已知类进行比较。
如果是后者,埃克斯的回答似乎是恰当的。
https://stackoverflow.com/questions/25275910
复制相似问题