避免使用多个if-else语句

时间:2017-08-03 17:32:11

标签: java generics

Item是一个带有子类Potion, Weapon. Shield的抽象类。

useItem()方法是在每个Item's子类

中定义的抽象方法

get_item返回班级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

这就是我创建的原因(来自@marsouf的帮助)hero.<Weapon>getItem(Weapon.class)

今天我创建了方法abstract public void useItem(); 因为它是Item类的一种方法,所以我可以使用hero.getItem().useItem()

4 个答案:

答案 0 :(得分:1)

使用Interface方法获取Item useItem()会更有意义。

然后有PotionShield等实现

通过这种方式,您可以避免必须进行投射并使其变得更复杂。

useItem()如果没有提供任何功能,则不属于抽象类,现在接口可以使用default方法。

答案 1 :(得分:1)

我的想法是使用仿制药的魔力,而不是强制转换

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
}

答案 2 :(得分:0)

在没有看到合同的情况下很难回答(hero.get_item(),hero.getItem())。

但你试过了吗?

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

答案 3 :(得分:0)

假设你已经开始按照你使用它的方式使用泛型...这就是方法。

首先,我创建了一些非常简单的类来模仿你的结构和你的另一个问题:一个使用特定抽象类实例的类。

Class SiteController extends Controller
{


    public function actionChangeLang($local) 
{
    $available_locales = [
        'ru-RU',
        'en-US'
    ];    

    if (!in_array($local, $available_locales)) {
        throw new \yii\web\BadRequestHttpException();
    }

    \Yii::$app->language = $local;

    retur

此程序在运行时打印出“Used item ACTwo!”

这里的关键是在UserClass(你的Character类)的getItemClass方法中。 此外,调用这些获取Class对象'getClazz'的方法是很常见的,因为有一个你不想覆盖的默认方法'getClass'。 在这里保持拼写是有意义的。