Po0*_*0ka 5 java inheritance casting class
我有一个字典,字符串作为键,类作为值,这包含我在游戏中的"实体"列表.
private static Map<String, Class> entitiesList = new HashMap<String, Class>();
public static void initEntitiesList()
{
entitiesList.put("npc_something", NpcSomething.class);
entitiesList.put("npc_thing", NpcThing.class);
entitiesList.put("npc_stuff", NpcStuff.class);
...
}
Run Code Online (Sandbox Code Playgroud)
这是一个示例层次结构.
Entity (abstract)
^
Mobile (abstract)
^
BaseCreature (abstract)
^
NpcSomething
Run Code Online (Sandbox Code Playgroud)
-Entity包含一个名为的方法"public void Input(String args)",可以在其他实体中重新定义.
- 当我调用Input("x")NpcSomething时,它应该super(arg)从它自己的类到Entity的类做一个链.
- 上面的所有类都有一个允许字符串作为参数的构造函数.
我有一个独立的静态方法用于创建我的实体的新实例,如下所示:
public static boolean createEntity(String entName, String args)
{
Class<?> entClass = null;
if ((entClass = entitiesList.get(entName)) != null)
{
Entity ent;
try
{
ent = (Entity)entClass.getDeclaredConstructor(String.class).newInstance("");
//this here failed.
//Method method = entClass.getMethod("input", new Class[] { ent.getClass() });
//method.invoke(ent, new Object[] {ent});
//java.lang.NoSuchMethodException: entities.NpcSomething.input(entities.NpcSomething)
//this here is really out of place, as i plan on having a hundred of entities and even more...
//if (entClass.isInstance(NpcSomething.class))
//i tried stuffs related to:
//T t = entClass.cast(ent);
//but i could not understand it at all even with documentation.
//basically i want to cast ent to entClass to call Input.
//right now, the line under calls Input on an Entity class, which is what i want to avoid.
ent.Input("Stuffs");
}
catch (InstantiationException ex) { ex.printStackTrace(); }
catch (IllegalAccessException ex) { ex.printStackTrace(); }
catch (IllegalArgumentException ex) { ex.printStackTrace(); }
catch (InvocationTargetException ex) { ex.printStackTrace(); }
catch (NoSuchMethodException ex) { ex.printStackTrace(); }
catch (SecurityException ex) { ex.printStackTrace(); }
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题.
EntCreator.createEntity("NpcSomething", "stuffs");
EntCreator.createEntity("NpcThing", "stuffs");
EntCreator.createEntity("NpcStuff", "stuffs");
Run Code Online (Sandbox Code Playgroud)
我想打电话Input();给NpcSomething,
我想打电话Input();给NpcThing,
我想打电话Input();给NpcStuff.
然后那些3将调用它们各自的超类代码,依此类推,直到它们到达实体.
这些都是实体"ent = (Entity)entClass.getDec...",因为我有Mobile,但也有Item,以及其他继承Input的类.然后使用该Entity,找到正确的子类,并调用该子类的Input.
短线问题:将"NpcSomething"创建为"实体",然后将实体强制转换为"NpcSomething的类"以调用该方法"Input(args)".
快速问题的答案.
-Q:为什么要这样做?
-A:使用预创建参数创建实体,例如:创建一个("NpcSomething", "health 20 healthmax 25").
-Q:为什么不使用instanceof?
-A:instanceof在静态类中我需要200多个,这将是一个糟糕的编程习惯.
-Q:为什么不在实体本身中移动输入法?
-A:我有很多不同的实体有不同的值,例如:NpcThing,唯一的飞行手机会有flyingSpeed,flyingEnergy ... ItemScroll,有text,textColor,textFont ......这些是我无法放入实体的东西,因为它需要instanceof,这对于不仅仅是ents来说是一种不好的做法.
-Q:你想将NpcSomething投射到实体吗?
-A:再读一遍.
-Q:你能提供更多信息吗?
-A:我也喜欢这样做.
-Q:你为什么不宣布为NpcSomething?
-A:因为ent可能是ItemStuff,ModelHouse等,它们不是继承自Mobile或BaseCreature ......
我没有找到如何做我想要的好的实际例子.
我在文档中找不到任何特别的内容.
欢迎任何帮助.
假设您Entity ent从newInstance()方法中获取了实例。这是调用input(String)该实例的方法的方式:
// See here, the .class argument passed is the type of parameter
// You're using `ent.getClass()` here. It won't work
Method method = ent.getMethod("input", String.class);
// then while invoking this method, you pass the argument:
// Call `invoke()` method of `Method` class
// First arg is the instance on which this method should be called
// Remaining arg is the argument to be passed to the method itself.
result = method.invoke(ent, args);
Run Code Online (Sandbox Code Playgroud)