簡體   English   中英

避免使用多個if-else語句

[英]Avoid using multiple if-else statements

Item是帶有子類別Potion, Weapon. Shield的抽象類Potion, Weapon. Shield Potion, Weapon. Shield

useItem()方法是在Item's每個子類中定義的抽象方法

Item get_item返回對象

getItem方法返回Item子類的對象

case "use":
    if (hero.get_item() instanceof Potion) {
        hero.<Potion>getItem(Potion.class).useItem();

    } else if (hero.get_item() instanceof Weapon) {
        hero.<Weapon>getItem(Weapon.class).useItem();

    } else if (hero.get_item() instanceof Shield) {
        hero.<Shield>getItem(Shield.class).useItem();
    }
    break;

有沒有一種方法可以將這段代碼壓縮為類似...

Class itemclass = hero.getItem().getClass();
hero.<itemclass>getItem(itemclass.class).useItem();

上面的代碼無法編譯,但是我正在尋找類似的東西。 我試圖避免if else語句,因為還有更多的項目。

編輯:

我最初不使用hero.get_item().useItem()原因是因為我試圖這樣做

Weapon sword = hero.get_item();

這樣我就可以訪問諸如sword.getDamage()

但是,我將收到錯誤error: incompatible types: Item cannot be converted to a Weapon

所以這就是為什么我創建hero.<Weapon>getItem(Weapon.class) (來自@marsouf的幫助)的原因hero.<Weapon>getItem(Weapon.class)

今天,我創建了方法abstract public void useItem(); 並且因為它是Item類的方法,所以我可以使用hero.getItem().useItem()

使用useItem()方法useItem() ItemInterface會更有意義。

然后為PotionShield等實現。

這樣,您就不必進行強制轉換並使它變得比實際更復雜。

useItem()沒有提供任何功能,則它不屬於抽象類,並且現在不需要的地方也可以包含default方法。

我的想法是在不強制轉換的情況下使用泛型的魔力

public class Character<T extends Item> {
    private T item;

    public Character (T item){
        this.item = item;
    }

    public T getItem(){
       return item;
    }
}

創建英雄時:

Character hero = new Character<Weapon>(new Weapon("sword"));

之后,您可以像這樣使用它:

hero.getItem().useItem(); // abstract method from Item class
hero.getItem().getPower(); //where power is a Weapon method

可以擴展的字符類如下:

public class Hero<T> extend Character<T>{
  //add there your custom methods or override Character methods
}

在不涉及合同的情況下很難回答(hero.get_item(),hero.getItem())。

但是您是否嘗試過:

Class<?> itemClass = hero.get_item().getClass();
hero.getItem(itemClass).useIt();

假設您已按照使用泛型的方式來使用泛型...這就是方法。

首先,我創建了一些非常簡單的類來模仿您和其他問題的結構:一個使用特定抽象類實例的類。

public class ACOne extends AbstractClass
{
    @Override
    public void use(){System.out.println("Used item ACOne!");}
}
public class ACTwo extends AbstractClass
{
    @Override
    public void use(){System.out.println("Used item ACTwo!");}
}
public abstract class AbstractClass
{
    public abstract void use();
}
public class UserClass
{
    private AbstractClass item;
    public UserClass (AbstractClass item)
    {
        this.item = item;
    }
    public Class<? extends AbstractClass> getItemClass()
    {
        return item.getClass();
    }
    public <T extends AbstractClass> T getItem (Class <? extends T> targetType)
    {
        return targetType.cast(this.item);
    }
    public void setItem (AbstractClass item)
    {
        this.item = item;
    }
}
public class CastingSubclasses
{
    public void testCastingSubclasses()
    {
        UserClass user = new UserClass(new ACOne());
        user.setItem(new ACTwo());
        user.getItem(user.getItemClass()).use();
    }
}

該程序在運行時會打印出“二手ACTwo!”。

關鍵是在UserClass(您的Character類)的getItemClass方法中。 而且,通常會調用這些獲得Class對象“ getClazz”的方法,因為有一個您不想覆蓋的默認方法“ getClass”。 在這里只保留拼寫是有意義的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM