2015-02-23 19 views
1

我正在使用Bukkit API为Minecraft开发一个League of Legends插件。无论如何,这个问题是普遍的。由于“英雄联盟”中有很多不同的角色,因此无法告诉玩家可以选择哪一个角色。那么我该如何创建一个可以解释这个变量的变量?传递多个类(Class <?extends foo> Interfaces和Abstract类)

所以我创建的基本接口,所有的字符类将实施:

public interface ChampInterface { 

    void setUp(Core plugin); 

    String getName(); 

    ItemStack getItem(); 

    void add(String name); 

    int getID(); 

} 

在此之后,我有一个实现了ChampInterface一个抽象类:

public abstract class ChampTemplate implements ChampInterface{ 

    private String name; 

    private int ID; 

    public String getName(){ 
     return name; 
    } 

    public int getID(){ 
     return ID; 
    } 

} 

最后,所有的字符将被创建为扩展抽象类,如下所示:

public class MasterYi extends ChampTemplate{ 

    Core plugin; 

    private String name; 

    private static List<String> players = new ArrayList<String>(); 

    public MasterYi(String name){ 
     this.name = name; 
    } 

    @Override 
    public void setUp(Core plugin) { 
     this.plugin = plugin; 
    } 

    @Override 
    public String getName() { 
     return "Master Yi"; 
    } 

    @Override 
    public ItemStack getItem() { 
     return new ItemStack(Material.WOOD_SWORD); 
    } 

    @Override 
    public void add(String name) { 
     players.add(name); 
    } 

} 

(忽略核心插件)

现在每次玩家加入游戏时,都会生成一个PlayerInfo类,其中存储所有统计信息。所以一旦玩家选择一个角色,这个类将被传递给玩家的PlayerInfo实例(用于制作这种简单起见,我把在构造函数中传递类):

public class PlayerInfo { 

    private Class<? extends ChampTemplate> champ; 

    private String name; 

    public PlayerInfo(String name, Class<? extends ChampTemplate> c){ 
     this.champ = c; 
     this.name = name; 
    } 

    public String getName(){ 
     //somehow say champ.getName() and it would reference the appropriate class 
     return null; 
    } 

} 

现在,我们终于可以得到我的问题。我已经将变量“champ”声明为Class类型,但是,只要我想从MasterYi类中调用getID()的抽象方法,那么当我写入“champ”时,该选项不会出现在下拉列表中。那么我怎么能让变量“champ”能够访问所有的抽象和接口方法,而不管我发送的字符类是什么?

感谢您通过这篇较长的文章与我联系,并感谢您的任何见解或建议! :)

+1

您不能在'Class'类型的对象上调用'getID'方法。你可以在类型为“ChampTemplate”的对象上调用'getID'。如果你想能够从'PlayerInfo'中访问冠军的id,则传递一个ChampTemplate而不是一个Class。例如: - 'public PlayerInfo(String name,ChampTemplate c)' – 2015-02-23 05:15:30

+0

我相当肯定你不需要这种泛型。所有的子类都可以存储在一个超类的引用变量中,并且可以通过执行'superClassVariable.methodName'来调用它们的方法。还有什么是在伊师傅类中'私人字符串名称'背后的推理?它目前看起来像一个无用的领域。 PlayerInfo中的'name'相同。 – Shashank 2015-02-23 05:31:58

回答

2

由于MasterYi延伸ChampTemplate,它可以用作它的替代品。意思是你不必检查它是否扩展它。

private ChampTemplate champ; 

public PlayerInfo(String name, ChampTemplate champ){ 
    this.champ = champ; 
} 

public String getName(){ 
    return champ.getName(); 
} 

然后,当你想使一个PlayerInfo对象,你可以在MasterYi对象传递。

MasterYi my = new MasterYi("Test"); 

PlayerInfo pi = new PlayerInfo("Bob", my); 

而且你可以从MasterYi对象获得冠军的名字,因为它被覆盖。

pi.getName(); //Returns "Master Yi" 

真的,你不必检查任何东西。只需存储一个ChampTemplate并传入扩展它的任何对象。

编辑:使用接口,它们是什么。 除了创建一个接口,然后让一个抽象类实现该接口,然后让另一个类最终扩展该接口,您可以将接口实现到主类中。

public interface IChampion { 

    void setUp(Core plugin); 

    String getName(); 

    ItemStack getItem(); 

    void add(String name); 

    int getID(); 

} 

然后让你的MasterYi(或任何其他的冠军你添加)实现该接口。

public class MasterYi implements IChampion{ 

    Core plugin; 

    private String name; 

    private static List<String> players = new ArrayList<String>(); 

    public MasterYi(String name){ 
     this.name = name; 
    } 

    public void setUp(Core plugin) { 
     this.plugin = plugin; 
    } 

    public String getName() { 
     return "Master Yi"; 
    } 

    public ItemStack getItem() { 
     return new ItemStack(Material.WOOD_SWORD); 
    } 

    public void add(String name) { 
     players.add(name); 
    } 

} 

现在你没有抽象类了!

而使用上面的修复,只需将您的界面全部替换为ChampTemplate即可。

private IChampion champ; 

public PlayerInfo(String name, IChampion champ){ 
    this.champ = champ; 
} 

public String getName(){ 
    return champ.getName(); 
} 

获取名称仍然有效!

+1

完美!我来自C++,所以我不太清楚如何从该语言翻译这个。这正是我所期待的! :d – 2015-02-23 07:14:04

相关问题