Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当用户传入其他类时,如何允许类构造其他类?_Java_Oop - Fatal编程技术网

Java 当用户传入其他类时,如何允许类构造其他类?

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

假设你有一个类群体,群体会生成一个内部的个体列表。用户希望将一个未构造的单个子类传递给Population,并让Population完成构造这些子类的工作,不管传递了什么子类

  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 for
ClassI-know工厂建议优于反射。为什么?@Ben B-工厂比基于反射的解决方案更健壮,因为它们是自动类型检查。如果存在与类型相关的错误,它们可能会在编译时被发现。反射速度也较慢,因为类型检查会在运行时重复执行,而不是在编译时执行一次。实际上,您的代码有很大的问题。我想我已经了解了您试图编写的内容……但您可能希望这样做清理一下。哦,我想我明白你想做什么了。我很困惑,因为你有一些额外的括号。@Ben B-我不知道你在说什么。请解释一下。