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();
}
}