java - 创建与子类相同类型的对象

标签 java inheritance types subclass superclass

我正在设计一个遗传算法库,目前正在构建 Genome 类。此类包括几种用于创建、变异、交叉和评估基因组的方法,并将成为该库的核心。这个抽象类有两个子类StaticGenomeVariableGenome。这些类为固定或可变长度基因组提供附加功能。

最终,任意两个基因组的交叉应该独立于基因组类型。也就是说,singlePointCrossover(Genome parent2) 方法接受两个基因组,并返回一个新的 Genome 对象,它是两个父基因组的特殊组合。但是,因为 Genome 是一个抽象类,我不能实例化一个新的 Genome 对象,因为它是后代。

如何从父类(super class)返回与子类类型相同的新对象?

如有任何帮助,我们将不胜感激。

基因组类:

public abstract class Genome <ElementType> {
    private String name;
    private List<AbstractGenomeElement<ElementType> > elements;

    // Mutation Methods //////////////////////////////////////////////
    public AbstractGenomeElement<ElementType> mutateElement(AbstractGenomeElement<Integer> element) {
        return this.mutateElementAtIndex(this.getElements().indexOf(element));
    }

    public AbstractGenomeElement<ElementType> mutateElementAtIndex(int i) {
        return this.getElement(i).mutate();
    }

    // Crossover Methods //////////////////////////////////////////////
    public Genome<ElementType> singlePointCrossover(Genome<ElementType> genome2){
        return multiPointCrossover(genome2, 1);
    }

    public Genome<ElementType> twoPointCrossover(Genome<ElementType> genome2){
        return multiPointCrossover(genome2, 2);
    }

    public Genome<ElementType> multiPointCrossover(Genome<ElementType> genome2, int crosses){
        List<AbstractGenomeElement<ElementType>> newElements= new ArrayList<AbstractGenomeElement<ElementType>>();
        Integer nums[] = new Integer[length-1];

        for (int i = 0; i < length-1; i++) { nums[i] = i+1; }

        List<Integer> shuffled = Arrays.asList(nums);
        Collections.shuffle(shuffled);
        shuffled = shuffled.subList(0, crosses);
        boolean selectFromParentA = true;
        for(int i = 0; i < length; i++){
            if(shuffled.contains((Integer)i)){
                selectFromParentA = !selectFromParentA;
            }
            if(selectFromParentA) newElements.add(this.getElement(i));
            else newElements.add(genome2.getElement(i));
        }
        // Code fails at this point. "Can not instantiate the type Genome"
        return new Genome<ElementType>(name, newElements);
    }
}

两个子类:

public class StaticGenome<ElementType> extends Genome<ElementType> {

}

public class VariableGenome<ElementType> extends Genome<ElementType> {

}

以及我用于测试的主要方法:

public static void main(String [] args){
    Genome<IntegerElement> genomeA = new StaticGenome<IntegerElement>("Genome A", 50);
    Genome<IntegerElement> genomeB = new StaticGenome<IntegerElement>("Genome B", 50);

    Genome<IntegerElement> offspring = genomeB.uniformCrossover(genomeA.elementCrossover(genomeA.multiPointCrossover(genomeB, 3)));
    offspring.setName("Offspring");
    System.out.println(offspring);
}

最佳答案

可以在抽象类中引入如下方法,并在子类中实现。

protected abstract Genome<ElementType> newInstance(String name, List<AbstractGenomeElement<ElementType>> elements);

当子类实现它时,它们可以返回正确的实例。即:他们自己的新实例。在您的交叉方法中,您可以调用此方法而不是执行“新基因组”

关于java - 创建与子类相同类型的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16381606/

相关文章:

java - Hibernate可以批量数据库查询二级缓存中集合未命中的情况吗?

java - 我的子类如何正确继承静态变量

types - golang 类型断言使用 reflect.Typeof()

c++ - 将迭代器返回到 C 数组的方法的正确类型声明

java - 为什么 SocketTimeoutException 使我的程序卡住?

java - 如何有效地搜索 HashMap 中所有值的子字符串?

C++ 静态和动态绑定(bind)行为

typescript - 描述已知某些键的 typescript 对象

java - 带通知的 Activity 导航

c++ - 编译器找不到在基类中实现的虚函数