Java—通过添加新类而不修改任何其他内容来添加功能
如何使类Java—通过添加新类而不修改任何其他内容来添加功能,java,reflection,Java,Reflection,如何使类A、B、C具有功能F,然后将类D添加到bin/并获得与F不同的功能,而不以任何方式修改A、B或C 我在Minecraft上看到过这种情况。使用ModLoader,您可以将类从ModLoader复制到Minecraft。然后,您可以简单地将一个以“mod_2;”开头的新类放入Minecraft jar,它会为游戏添加新的内容。在任何时候都没有直接引用“mod_Foobar”类的类 最好是一个小的工作示例和指向任何进一步阅读的链接。类路径用于加载类,并且是有序的,因此如果您将类放在原始类之前
A
、B
、C
具有功能F,然后将类D
添加到bin/
并获得与F不同的功能,而不以任何方式修改A
、B
或C
我在Minecraft上看到过这种情况。使用ModLoader,您可以将类从ModLoader复制到Minecraft。然后,您可以简单地将一个以“mod_2;”开头的新类放入Minecraft jar,它会为游戏添加新的内容。在任何时候都没有直接引用“mod_Foobar”类的类
最好是一个小的工作示例和指向任何进一步阅读的链接。类路径用于加载类,并且是有序的,因此如果您将类放在原始类之前,您的类将被加载,而不是原始类。我想这都是关于应用基本OO原则的 简单的继承允许您实现。在设计良好的系统中,这是将新行为引入系统的良好起点 是工具箱中的另一种软件设计模式,可以在运行时选择算法的行为 (结合反射和上面提到的模式)可以创建一个系统,在这个系统中,您可以将类“删除”到现有系统中,以便在不更改其核心的情况下添加新功能 您还可以在启动时查找有趣的(带注释的)类来修改运行时行为 我相信MindCraft是一个设计良好的系统,应用了比这里描述的更多的模式 最终,这一切归结为良好的设计和在正确的位置应用正确的模式
public class Reflection {
public void sayHello(String theClass){
//Since Mod classes are in package 'mod', we precede their name accordingly.
Class aClass = Class.forName("mod." + theClass);
aClass.getMethod("sayHi").invoke(aClass.newInstance());
}
public static void main(String[] args) {
//Get a list of the compiled classes in the 'mod' folder
String path = "./bin/mod";
String fileName;
File folder = new File(path);
List<File> fileList = Arrays.asList(folder.listFiles());
//Iterate through the list of classes to invoke their methods
Iterator<File> it = fileList.iterator();
while(it.hasNext()){
fileName = it.next().getName();
//When invoking the sayHello method, we remove the file extension
new Reflection().sayHello(fileName.replace(".class", ""));
}
}
}
ModB类:
public class ModB {
public void sayHi(){
System.out.println("Hi! I'm ModB.");
}
}
请注意:
- 为了澄清示例,我删除了一些必要的异常处理
- Mod类位于名为“Mod”的包中。编译后,它们出现在bin/mod中。也许有一种更干净的扫描方式
- Mod类被编译、打包到jar中并包含在构建路径中
反射
,因为我感觉它牵涉其中(尽管我对它一无所知)。如果你知道它是不相关的,请说出来,或者删除它。我不知道确切的方法,但我认为你应该能够找到你的类路径上的所有类,然后通过反射加载它们。或者您可以找到.class文件并通过某种机制加载它们(javassist应该可以工作,但可能还有其他功能)。Eclipse通过配置文件(即加载它的插件)完成这些事情。等等这一切都会消耗在寻找您可能希望在类路径上使用的文件上。这可能是策略设计模式在起作用吗经过反思,我终于开始明白它的作用。我的问题的答案基本上是:“反思”,我给它贴上了标签。我基本上在标签上回答了我的问题。这个问题过于宽泛。请随意投票结束,因为这“不是一个真正的问题”
public class ModB {
public void sayHi(){
System.out.println("Hi! I'm ModB.");
}
}