java - 从动态转换的超类调用子类方法
java - Calling a subclass method from dynamically casted superclass
1:
我有一个字典,其中一个字符串作为键,一个 class 作为值,它包含我在游戏中的 "entities" 列表。
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);
...
}
2:
这是一个层次结构示例。
Entity (abstract)
^
Mobile (abstract)
^
BaseCreature (abstract)
^
NpcSomething
-实体包含一个名为"public void Input(String args)"
的方法,
可以在其他实体中重新定义。
-当我在 NpcSomething 上调用 Input("x")
时,它应该做一个从它自己的 class 到实体的 class.
的 super(arg)
链
- 上述所有 classes 都有一个允许字符串作为参数的构造函数。
3:
我有一个独立的静态方法用于创建我的实体的新实例,它是这样的:
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(); }
}
}
4:
我的问题。
EntCreator.createEntity("NpcSomething", "stuffs");
EntCreator.createEntity("NpcThing", "stuffs");
EntCreator.createEntity("NpcStuff", "stuffs");
我想在 NpcSomething 上调用 Input();
,
我想在 NpcThing 上调用 Input();
,
我想在 NpcStuff 上调用 Input();
。
然后这 3 个将调用它们各自的 superclass 代码,依此类推,直到它们到达 Entity.
因为我有 Mobile、Item 和其他继承 Input 的 classes,所以它们被转换为 "ent = (Entity)entClass.getDec..."
的实体。
然后使用该实体,找到正确的 subclass,并调用该 subclass.
的输入
短线问题:将 "NpcSomething" 创建为 "Entity" 然后将实体转换为 "NpcSomething's class" 以调用方法 "Input(args)"
.
5:
快速问题的答案。
-问:为什么要这样做?
-A:创建带有预创建参数的实体,例如:创建一个("NpcSomething", "health 20 healthmax 25")
.
-问:为什么不使用instanceof?
-A:我在那个静态 class 中需要超过 200 instanceof
,这将是一个糟糕的编程习惯。
-Q:为什么不把输入法移到Entity里面?
-A:我有许多具有不同价值观的不同实体,
前任:
NpcThing,唯一的飞行移动设备会有飞行速度,飞行能量......
ItemScroll,有文本,textColor,textFont ...
这些是我不能放在 Entity 中的东西,因为它需要 instanceof
,这对不止 ents 来说是一个不好的做法。
-Q: 是否要将 NpcSomething 转换为实体?
-A: 再读一遍。
-问:能否提供更多信息?
-A:我也很想做。
-问:你为什么不把ent声明为NpcSomething?
-A:因为 ent 可能是 ItemStuff、ModelHouse 等,它们不是从 Mobile 或 BaseCreature 继承的...
6:
我没有找到如何做我想做的好的实际例子。
我在文档中找不到任何特别针对此的内容。
欢迎任何帮助。
因为方法调用的优先级高于强制转换。
您应该在方法调用之前强制强制转换,方法是用方括号
将其括起来
ent = ((Entity)entClass).getDeclaredConstructor(String.class).newInstance("");
假设您从 newInstance()
方法中获得了 Entity ent
实例。这是您为该实例调用 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);
1:
我有一个字典,其中一个字符串作为键,一个 class 作为值,它包含我在游戏中的 "entities" 列表。
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);
...
}
2:
这是一个层次结构示例。
Entity (abstract)
^
Mobile (abstract)
^
BaseCreature (abstract)
^
NpcSomething
-实体包含一个名为"public void Input(String args)"
的方法,
可以在其他实体中重新定义。
-当我在 NpcSomething 上调用 Input("x")
时,它应该做一个从它自己的 class 到实体的 class.
的 super(arg)
链
- 上述所有 classes 都有一个允许字符串作为参数的构造函数。
3:
我有一个独立的静态方法用于创建我的实体的新实例,它是这样的:
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(); }
}
}
4:
我的问题。
EntCreator.createEntity("NpcSomething", "stuffs");
EntCreator.createEntity("NpcThing", "stuffs");
EntCreator.createEntity("NpcStuff", "stuffs");
我想在 NpcSomething 上调用 Input();
,
我想在 NpcThing 上调用 Input();
,
我想在 NpcStuff 上调用 Input();
。
然后这 3 个将调用它们各自的 superclass 代码,依此类推,直到它们到达 Entity.
因为我有 Mobile、Item 和其他继承 Input 的 classes,所以它们被转换为 "ent = (Entity)entClass.getDec..."
的实体。
然后使用该实体,找到正确的 subclass,并调用该 subclass.
短线问题:将 "NpcSomething" 创建为 "Entity" 然后将实体转换为 "NpcSomething's class" 以调用方法 "Input(args)"
.
5:
快速问题的答案。
-问:为什么要这样做?
-A:创建带有预创建参数的实体,例如:创建一个("NpcSomething", "health 20 healthmax 25")
.
-问:为什么不使用instanceof?
-A:我在那个静态 class 中需要超过 200 instanceof
,这将是一个糟糕的编程习惯。
-Q:为什么不把输入法移到Entity里面?
-A:我有许多具有不同价值观的不同实体,
前任:
NpcThing,唯一的飞行移动设备会有飞行速度,飞行能量......
ItemScroll,有文本,textColor,textFont ...
这些是我不能放在 Entity 中的东西,因为它需要 instanceof
,这对不止 ents 来说是一个不好的做法。
-Q: 是否要将 NpcSomething 转换为实体?
-A: 再读一遍。
-问:能否提供更多信息?
-A:我也很想做。
-问:你为什么不把ent声明为NpcSomething?
-A:因为 ent 可能是 ItemStuff、ModelHouse 等,它们不是从 Mobile 或 BaseCreature 继承的...
6:
我没有找到如何做我想做的好的实际例子。
我在文档中找不到任何特别针对此的内容。
欢迎任何帮助。
因为方法调用的优先级高于强制转换。 您应该在方法调用之前强制强制转换,方法是用方括号
将其括起来ent = ((Entity)entClass).getDeclaredConstructor(String.class).newInstance("");
假设您从 newInstance()
方法中获得了 Entity ent
实例。这是您为该实例调用 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);