我想定义一个创建不同类型对象的函数,这些对象共享相同的基类。我想传入对象类型并使用函数创建对象,然后修改其属性。问题是创建所有这些对象的主类没有对象的属性,因此代码无法编译。
示例:
public void new_generic_report(Class report_class, String report_name) {
Report new_report = this.reportManager.createReport(report_class);
new_report.set_name(report_name);
}
调用new_generic_report(GreenReport.class, "green_report");
失败,因为new_report属于Report类而不是GreenReport,因此它没有.set_name方法。
我知道我可以在主要的Report类中实现.set_name方法(以及其他常用方法),但我正在编写代码来与我无法修改的API进行交互。
答案 0 :(得分:1)
如果您确定createReport返回正确类的实例,则可以执行强制转换:
((SpecialClass)new_report).set_name(report_name);
另一种方法是使用反射:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
static class Base {};
static class Child extends Base {
public void setName(final String name) {
System.out.println("setName("+name+")");
}
}
public static void main(String[] args) {
new Test().new_generic_report(Child.class, "Testname");
}
public void new_generic_report(final Class clazz, final String name) {
Base base = createBase(clazz);
try {
Method m = clazz.getMethod("setName", String.class);
m.invoke(base, name);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private Base createBase(Class report_class) {
return new Child();
}
}
当然,只有返回的实例实现了方法,这才有效。
答案 1 :(得分:1)
为您的报告创建一个父类:
public abstract class NamedReport extends Report
{
public abstract void setName(String name);
}
class GreenReport extends NamedReport {
@Override
public void setName(String name) {
}
}
然后只需在您的方法中投射您的课程:
public void new_generic_report(Class report_class, String report_name) {
Report new_report = this.reportManager.createReport(report_class);
if (new_report instanceof NamedReport)
{
((NamedReport)new_report).set_name(report_name);
}
}