Java 避免使用多个if-else语句

Java 避免使用多个if-else语句,java,generics,Java,Generics,Item是一个抽象类,包含子类药剂、武器。屏蔽 useItem()方法是在每个Item的子类中定义的抽象方法 get\u item类的返回对象item case "use": if (hero.get_item() instanceof Potion) { hero.<Potion>getItem(Potion.class).useItem(); } else if (hero.get_item() instanceof Weapon) {

Item
是一个抽象类,包含子类
药剂、武器。屏蔽

useItem()
方法是在每个
Item的
子类中定义的抽象方法

get\u item
类的返回对象
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;
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;
因此,我可以访问诸如
Swarm.getDamage()之类的方法

但是,我会得到错误
错误:不兼容类型:物品无法转换为武器

这就是为什么我创建了(来自@marsouf的帮助)
hero.getItem(wearm.class)

今天我创建了方法
abstract public void useItem()

由于它是
Item
类的一种方法,我可以使用
hero.getItem().useItem()

在没有看到涉及到合同的情况下很难回答(hero.get\u Item(),hero.getItem())

但你有没有试过:

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

使用方法
useItem()
Item
提供一个
接口将更有意义

然后实现
药剂
盾牌

通过这种方式,您可以避免强制转换,并使其更加复杂


useItem()
不属于抽象类,如果它不提供任何功能,那么现在不太需要的接口可以有
默认的
方法。

我的想法是使用泛型的魔力而不强制转换

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

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

    public T getItem(){
       return item;
    }
}
可以像这样扩展字符类:

public class Hero<T> extend Character<T>{
  //add there your custom methods or override Character methods
}
公共类英雄扩展角色{
//在那里添加自定义方法或重写字符方法
}

假设您已经习惯了使用泛型的方式。。。这是怎么做的

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

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();
    }
}
公共类ACOne扩展了抽象类
{
@凌驾
public void use(){System.out.println(“Used item ACOne!”);}
}
公共类ACTwo扩展了抽象类
{
@凌驾
public void use(){System.out.println(“Used item ACTwo!”);}
}
公共抽象类AbstractClass
{
公开摘要无效使用();
}
公共类用户类
{
私有抽象类项目;
公共用户类(AbstractClass项)
{
this.item=项目;
}

公共类如果
useItem()
是在
Item
上定义的,这就是
get\u Item()
返回的,为什么不只是
hero.get\u Item().useItem()
?既然所有类似乎都实现了useItem()方法,那么您应该能够简单地执行hero.get\u Item().useItem();这不起作用。[@kevinLloyd在你的例子中,你不需要知道子类。
useItem
的正确实现将被运行时调用,即使声明的类型只是
Item
,实际上我会尝试一下。我昨天没有创建use Item函数,所以我不得不创建一个非常奇怪的函数,但它不起作用。它给我llegal start of type error是否可以更新您的问题,添加get_item()和getItem()的签名?否则,我们只是猜测你的api是关于什么的。我在itemClass声明上有一个输入错误,现在就试试。但是如果你只提供你的hero方法的签名,会容易得多。根据你的想法,可以用setter方法更改hero拥有的项吗?我同意marsouf的回答,你只能将项更改为相同类型,f或者我的例子,英雄只能有另一件武器,但不能有药剂。如果你想用setter更换武器,但有不同的方法,请将使用物品的逻辑移动到物品类别/子类别或一个delagate@kevinLloyd那么你应该接受marsouf的回答:
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
}
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();
    }
}