返回类型基于用户选择?

时间:2014-08-12 23:48:48

标签: java inheritance return-type

这是一个相当困难的问题,但这是我能想到的最好的。

基本上我有一个Animal Class,一个继承自Animal Class的昆虫类,以及一个继承自昆虫类的Spider,Woodlouse和Worm类

例如,我有一个名为InsectStorage的类,它在一个数组中定义并存储了许多Insect对象(所以不同种类的蠕虫,woodlouses等数组)。我希望用户能够选择一只昆虫,并在这个类中为玩家分配一只昆虫。

使用

设置昆虫是可以实现的
Spider blackWidow = new Spider()
Spider wolfSpider = new Spider()
Spider[] spiderStorage = new Spider[2]

worm lumbricusTerrestris = new Worm()
...
switch (insectSelect)

case: "Black Widow"

所以switch语句是第一个复杂化产生的地方,但是可以通过创建一个类型为Worm,Spider和Woodlouses的selectedPlayerInsect并根据选择设置每个复杂来解决这个问题。

但是我怎么可能创建一个getPlayerInsect()方法呢?如果选择了蜘蛛,我需要能够返回Spider,如果选择了蠕虫,我需要返回蠕虫。

我可以尝试为每个昆虫子类创建一个playerObject并创建四个getPlayerXX()方法,但这意味着每次我想在我的main方法中调用getPlayerSpider()或getPlayerWorm()时,我必须将if语句放入检查选择了哪个对象(非常不方便)。

我尝试摆弄Wrapper课程,但也无法使这些工作(如果我还是要使用playerIsWorm等)。

很多文字,代码不多,但我不认为我的解释真的需要代码。 我怎么能(如果可以的话)解决这个问题?

3 个答案:

答案 0 :(得分:0)

您可以将Clases / Enums用于不同类型的昆虫。

Enum Spiders {BLACKWIDOW, WOLFSPIDER};

Spider firstSpider = Spiders.BLACKWIDOW;
if (firstSpider == Spiders.BLACKWIDOW) ...

VS

class BlackWidow extends Spider {... }
class WolfSpider extends Spider { ... }
Spider firstSpider = new BlackWidow();
if (firstSpider instanceof BlackWidow) ....

在这种情况下,您将使用instanceof或.class(对于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);
    ...

或者类似的。你在评论中询问如何返回蜘蛛或工作,你会通过返回两者的超类型来做到这一点(默认情况下是Object,但更好的是特定的东西):

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

答案 1 :(得分:0)

我不确定你是否想要"播放器"能够选择昆虫OBJECT(woodlouse,worm,spider)的类型或昆虫的类型' name' (缺乏一个更好的术语 - Blackwidow,wolfspider等)。

如果是前者,似乎你可以利用getClass()方法(http://www.tutorialspoint.com/java/lang/object_getclass.htm)并在为玩家创建新昆虫时将其与枚举列表中的已知类进行比较。

如果是后者,eckes的答案似乎是合适的。

答案 2 :(得分:0)

因此,立即解决问题的方法是进行类型检查 - 基本上就是你所说的。这很丑陋,但根据你的想法,它可以工作。

但是,我认为还有一个更深层次的问题要考虑。

如果您正确设计了类,那么昆虫类的实际“类型”应该无关紧要。您应该将不同的逻辑构建到子类本身中。这使得将来更容易构建在顶部。 @PM 77-1说得最好 - 你需要按照应该使用的方式使用多态。

相反,只需要:

public Insect getPlayerInsect(){
  return playerInsect;
}

也许你的主要方法看起来像这样:

Insect player = getPlayerInsect();
player.eat(); // Everything eats

您不需要(不应该)在该eat语句中构建复杂的if / else逻辑。

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不适用于所有子类,则通常意味着您需要重新构建类层次结构。

相关问题