Java 当用户传入其他类时,如何允许类构造其他类?
假设你有一个类群体,群体会生成一个内部的个体列表。用户希望将一个未构造的单个子类传递给Population,并让Population完成构造这些子类的工作,不管传递了什么子类Java 当用户传入其他类时,如何允许类构造其他类?,java,oop,Java,Oop,假设你有一个类群体,群体会生成一个内部的个体列表。用户希望将一个未构造的单个子类传递给Population,并让Population完成构造这些子类的工作,不管传递了什么子类 public class Population{ private List<Individual> indiList = new ArrayList(25); /*I know this won't work for multiple reasons, but shows the id
public class Population{
private List<Individual> indiList = new ArrayList(25);
/*I know this won't work for multiple reasons, but shows the idea*/
public void addIndividualsOfType(Individual individual){
for (ListIterator it = indiList.listIterator(); it.hasNext(); ){
it.next()
it.add(individual.construct(param1, param2, param3);
}
}
}
public abstract class Individual{
SomeType param1;
...
public Individual(SomeType param1, SomeType param2, SomeType param3){
this.param1 = param1;
...
}
}
public class HappyIndividual extends Individual{
...
}
public class SadIndividual extends Individual{
...
}
公共类人口{
私有列表indiList=newarraylist(25);
/*我知道由于多种原因,这不起作用,但这表明了这个想法*/
public void addIndividualsOfType(个人){
for(ListIterator it=indiList.ListIterator();it.hasNext();){
it.next()
it.add(单个.construct)(param1,param2,param3);
}
}
}
公共抽象类个人{
某些类型参数1;
...
公共个人(SomeType参数1、SomeType参数2、SomeType参数3){
this.param1=param1;
...
}
}
公共类快乐个体扩展个体{
...
}
公共类个体扩展了个体{
...
}
我希望能够打一个电话,比如population.addIndividualsOfType(HappyIndividual)
很明显,由于很多原因(比如传递一个未实例化的类),这段代码都不起作用。我只是想说明我想做什么,这不是为什么上面的代码不起作用的问题。我知道它不起作用,这就是为什么我不知道如何做这样的事情
我整天都在摆弄构建器和静态工厂方法。问题是我们在这里讨论的是子类。子类不能很好地处理静态。如果我给个人一个静态工厂方法,那么我最终会创建个人,而不是快乐的个人。类似的问题也会发生在构建器上。我也不想让这一点过多复杂的
我觉得这应该很容易,但我有麻烦了。谢谢
我希望能够像population.addIndividualsOfType(HappyIndividual)一样拨打电话
当您要求这样做时,您已经非常接近了。您可以传递HappyIndividual.class
,它是表示HappyIndividual
类的类对象。此对象本身的类型表示运行时的类
然后,您的方法将如下所示:
public void addIndividualsOfType(Class<? extends Invididual> clazz) {
for (ListIterator it = indiList.listIterator(); it.hasNext(); ){
it.next();
it.add(clazz.newInstance());
}
}
Constructor<? extends Individual> cons = clazz.getConstructor(
param1.getClass(), param2.getClass(), param3.getClass());
it.add(cons.newInstance(param1, param2, param3));
public void addIndividualsOfType(Class传入相关类(例如,HappyPerson.Class
),通过调用Class.getConstructor(arg…
)获取构造函数,然后实例化实例。基本上有两种方法:
您可以沿着当前路径继续,并使用反射来构造类:
public void addIndividualsOfType(Class<? extends Individual> clazz){
for (ListIterator it = indiList.listIterator(); it.hasNext(); ){
it.next()
it.add(clazz.newInstance()); // using no-args constructor
}
}
(我省略了异常处理……但你明白了。)
但是,一种更好的方法是重构代码,以便传入factory对象,而不是类
对象。例如:
public interface IndividualFactory {
public Individual create(T1 p1, T2 p2, T3 p3);
}
public static final IndividualFactory TALL_FACTORY = new IndividualFactory() {
public Individual create(T1 p1, T2 p2, T3 p3) {
return new TallIndividual(p1, p2, p3);
}
};
public void addIndividualsOfType(IndividualFactory factory){
for (ListIterator it = indiList.listIterator(); it.hasNext(); ){
it.next()
it.add(factory.create(param1, param2, param3);
}
}
请注意,基于工厂的解决方案可以进行静态类型检查。相比之下,反射版本必须处理大量与类型相关的运行时异常。请告诉我…+1 forClassI-know工厂建议优于反射。为什么?@Ben B-工厂比基于反射的解决方案更健壮,因为它们是自动类型检查。如果存在与类型相关的错误,它们可能会在编译时被发现。反射速度也较慢,因为类型检查会在运行时重复执行,而不是在编译时执行一次。实际上,您的代码有很大的问题。我想我已经了解了您试图编写的内容……但您可能希望这样做清理一下。哦,我想我明白你想做什么了。我很困惑,因为你有一些额外的括号。@Ben B-我不知道你在说什么。请解释一下。