尝试为遗传算法编写一些通用代码,我有一个抽象类基因型如下:
public abstract class Genotype {
private ArrayList<Gene> genotype = new ArrayList<Gene>();
//...
public Genotype(ArrayList<Gene> genotype) {
setGenotype(genotype);
setGenotypeLength(genotype.size());
}
public abstract Phenotype<Gene> getPhenotype();
public abstract void mutate();
//...
}
这个类旨在扩展,子类显然提供了getPhenotype()和mutate()的实现。但是,我还有一个第二个类,它接受两个Genotype对象作为参数,并返回一个包含Genotype对象的ArrayList。由于此时我不知道扩展的Genotype对象的类型,我需要使用泛型参数,如下所示:
public class Reproducer {
//...
private <G extends Genotype> ArrayList<Genotype> crossover(G parent1, G parent2) {
ArrayList<Genotype> children = new ArrayList<Genotype>();
ArrayList<Gene> genotypeOne = ArrayListCloner.cloneArrayList(parent1.getGenotype());
ArrayList<Gene> genotypeTwo = ArrayListCloner.cloneArrayList(parent2.getGenotype());
//one point crossover
int p = gen.nextInt(genotypeOne.size());
for (int i = 0; i < p; i++) {
genotypeOne.set(i, genotypeOne.get(i));
genotypeTwo.set(i, genotypeTwo.get(i));
}
for (int i = p; i < 10; i++) {
genotypeOne.set(i, genotypeTwo.get(i));
genotypeTwo.set(i, genotypeOne.get(i));
}
children.add(new G(genotypeOne)); //THROWS ERROR: Cannot instantiate the type G
children.add(new G(genotypeTwo)); //THROWS ERROR: Cannot instantiate the type G
return children;
}
}
但是,由于我需要在ArrayList中返回两个G类型的对象,所以我显然遇到了无法实例化新Genotype对象的问题,因为它们是1.泛型类型,大概是2. abstract。
这可能是将所有事情放在一起的坏方法,但如果有人有一个很好的解决方案。谢谢。
答案 0 :(得分:3)
我建议您在Genotype
类
public abstract class Genotype {
public abstract GenoType newInstance();
}
答案 1 :(得分:1)
您可以使用abstract factory pattern。由于您的工厂只需要一种工厂方法,这可以说是一种退化的情况,但它可能就是您所需要的。您应该将工厂实例传递给Reproducer
对象,可能作为某种方法的参数。它不漂亮,但至少你现在对对象创建有抽象。
更好的解决方案可能是改变您的架构。为什么不忘记Genotype
班?您的基因型表示基本上是基因列表。您可以在这些列表上创建具有(通用)操作的实用程序类,并在其他类中使用这些操作。以下是我的意思草图:
public static <G extends Gene> List<? extends G> mutate( List<G> genotype ) { ... }
public static <G extends Gene> List<List<? extends G>> crossover( List<G> p1, List<G> p2 ) { ... }
作为旁注:赞成在类类型上声明接口类型;在您的示例中,您不使用List
界面。
最后一点注意:在您的示例中,您并不真正需要泛型类型。如果将参数类型声明为Genotype
,则会得到相同的解决方案(具有相同的问题)。类型X参数接受任何类型为X的对象(包括子类型!)作为参数。