这是一个相当困难的问题,但这是我能想到的最好的。
基本上我有一个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等)。
很多文字,代码不多,但我不认为我的解释真的需要代码。 我怎么能(如果可以的话)解决这个问题?
答案 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
不适用于所有子类,则通常意味着您需要重新构建类层次结构。