最初にクラスを考えてみましょうGene
: あなたの仕様 ( 4 つの数字を持つ char [] である Gene がありますchar
) によると、クラスの属性として配列が必要です。さらに、このクラスは複製可能でなければなりません。次に、このクラスにインターフェースを実装させる必要があります。この目的のために、クラスがインターフェースを実装Cloneable
することを宣言し(単にクラス定義に書き込むだけです) 、このクラスにメソッドを実装する必要があります(このメソッドでは、オブジェクト フィールドのディープ コピーを作成し、複製されたオブジェクトを返す必要があります。詳細については、以下のコードを参照してください)。Gene
Cloneable
implements Cloneable
clone
import java.util.Arrays;
/*
* Definition of the class that also includes the declaration
* of the implementation of the Cloneable interface.
*/
public class Gene implements Cloneable {
/*
* The length of a gene.
* It is defined as constant (final) in order to use the same value
* in the whole class, where and when necessary.
*/
private static final int GENE_LENGTH = 4;
/*
* In biology a gene it corresponds to a sequence of nucleic acids,
* so I thought of naming m_sequence this field.
*/
private char m_sequence[];
/*
* This constructor allows you to instantiate a new object from a char array.
*/
public Gene(char sequence[]) {
// The field m_sequence is initialized with a copy
// of the array specified in the constructor.
m_sequence = Arrays.copyOf(sequence, GENE_LENGTH);
}
/*
* Simple getter method.
* Since m_sequence is private, you need a method like this
* in order to access elements of the array.
*/
public char getUnit(int index) {
return m_sequence[index];
}
/*
* Simple setter method.
* Since m_sequence is private, you need a method like this
* in order to set the elements of the array.
*/
public void setUnit(int index, char unit) {
m_sequence[index] = unit;
}
/*
* The Cloneable declaration requires that this class has clone method.
* This method should return an Gene object within an Object.
*/
protected Object clone() throws CloneNotSupportedException {
// First, we invoke the clone method of the superclass
Gene clone = (Gene)(super.clone());
// Then, make the deep copy of the object.
// In this case the only field present in the Gene object is an array,
// then you must make a deep copy of this array: in order to make a deep
// copy of the array, you should use the Arrays.copyOf method.
clone.m_sequence = Arrays.copyOf(m_sequence, GENE_LENGTH);
return clone;
}
/*
* Get a representation of this object as a String.
* Just a method for simple testing.
*/
@Override
public String toString() {
return Arrays.toString(m_sequence);
}
}
copyOf
配列をコピーするためにクラスのメソッドを使用したことに注意してください (配列のコピーの詳細については、こちらArrays
をお読みください)。
Gene
オブジェクトのディープ コピーの機能を確認する簡単なテスト:
public static void main(String args[]) throws CloneNotSupportedException {
Gene g1 = new Gene(new char[]{'a', 'b', 'c', 'd'});
Gene g2 = (Gene)(g1.clone());
// now Let's modify g1
g1.setUnit(0, 'e');
g1.setUnit(1, 'f');
g1.setUnit(2, 'g');
g1.setUnit(3, 'h');
System.out.println("g1: " + g1);
System.out.println("g2: " + g2); // g2 has not changed
}
したがって、次のようにcreateChild
メソッドを変更する必要があります。
public class Chromosome {
private static final int CHROMOSOME_LENGTH = 10;
/* Array of Gene object. */
private Gene genes[];
/* Default constructor. */
public Chromosome() {
// Simply allocates an array of 10 elements.
genes = new Gene[CHROMOSOME_LENGTH];
}
/*
* Simple getter method.
* Since m_Genes is private, you need a method like this
* in order to access elements of the array.
*/
public Gene getGene(int index) {
return genes[index];
}
/*
* Simple setter method.
* Since m_Genes is private, you need a method like this
* in order to set the elements of the array.
*/
public void setGene(int index, Gene gene) {
genes[index] = gene;
}
/* The method which make the cross-over. */
public Chromosome createChild(Chromosome parentA, Chromosome parentB) throws CloneNotSupportedException {
Chromosome child = new Chromosome();
// make the cross-over
for (int i=0;i<10; i++)
{
if (i<5)
{
// you need to call the clone() method
child.genes[i] = (Gene)(parentA.genes[i].clone());
}
else
{
// you need to call the clone() method
child.genes[i] = (Gene)(parentB.genes[i].clone());
}
}
return child;
}
}