Generics

Conkerchen

Grünschnabel
Habe eine Frage zu Generics. Am Besten erkläre ich es direkt mal an dem Beispiel, an dem ich gerade dran bin:

Ich habe eine Klasse Matrix zur Rechnung mit Matrizen. Hier möchte ich, dass als Einträge ausschließlich Elemente eingefügt werden können, die auch Elemente eines Körpers bzw. einer algebraischen Struktur sind, auf der zumindest zwei Operationen add und mult definiert sind. Als Körper habe ich jetzt eine Klasse Rational, die diese Eigenschaft erfüllt.

Jetzt habe ich außerdem eine Klasse Körper, von der Rational erbt, um in den Kreis der möglichen Elemente der Matrix mit aufgenommen zu werden.

Mein großes Problem ist nun, dass ich nicht weiß, wie ich meine Matrix initialisieren kann. Der code sieht wie folgt aus:

Code:
public Matrix initZero () {
	for (int i = 0; i < line; i++) {
		for (int j = 0; j < col; j++) {
			value[i][j] = ?
		}
	}
	return this;
}

Wie bekomme ich da jetzt eine Null rein? Also nicht die Integer-Null, auch nicht die null-Referenz (die ist ja schon drin). Ich möchte, dass entsprechend des Typs, den diese Matrix aufnimmt, das entsprechende Null-Element des Körpers eingefügt wird. Ich habe das mit Generics gemacht, was beim Einfügen auch ganz gut funktioniert. Alles, was nicht dem Typ der Matrix entspricht, wird schon zur Compile-Zeit für die Einfüge-Operation Abgelehnt.

Aber an dieser Stelle will ich aber ja nicht sicherstellen, dass ein entsprechender Typ beim Afuruf der Methode initZero() verlangt wird, sondern ich will, dass initZero() das Null-Element der Klasse des jeweiligen Typs herausfischt. Also etwa so:

Code:
value[i][j] = Field<Type>.ZERO.clone();

So geht es aber anscheinend nicht. Wie komme ich an das entsprechende Nullelement der Klasse Type? Oder mache ich hier grundsätzlich alles total falsch und verkehrt?
 
Zuletzt bearbeitet:
Hallo,

wie wärs denn damit?
Java:
package de.tutorials;

import java.lang.reflect.Array;

public class AlgebraicExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Matrix<Real> matrix = Matrix.create(3, 3, Real.ZERO);
		System.out.println(matrix);
	}

	static interface SupportsMult<T extends SupportsMult<T>> {
		T mult(T other);
	}

	static interface SupportsAdd<T extends SupportsAdd<T>> {
		T add(T other);
	}

	static interface Field<T extends Field<T>> extends SupportsAdd<Real>, SupportsMult<Real>{
		T zero();
		T one();
	}

	static class Matrix<T extends Field<T>> {
		int rows;
		int columns;
		T initialValue;
		T[][] data;
		
		@SuppressWarnings("unchecked")
		public Matrix(int rows, int columns, T initialValue) {
			this.rows = rows;
			this.columns = columns;
			this.initialValue = initialValue;
			this.data = (T[][]) Array.newInstance(initialValue.getClass(), rows, columns);
			init(this.initialValue);
		}
		
		public static <T extends Field<T>> Matrix<T> create(int rows, int columns, T initialValue){
			return new Matrix<T>(rows,columns,initialValue);
		}
		
		private void init(T initValue){
			for (int i = 0; i < rows; i++) {
				for (int j = 0; j < columns; j++) {
					data[i][j] = initValue;
				}
			}
		}
		
		public void set(int i, int j, T value){
			data[i][j] = value;
		}
		
		public T get(int i, int j){
			return data[i][j];
		}
		
		public String toString() {
			StringBuilder sb = new StringBuilder();
			sb.append("{");
			sb.append("\n");
			for (int i = 0; i < rows; i++) {
				for (int j = 0; j < columns; j++) {
					sb.append(data[i][j]);

					if (j + 1 < columns) {
						sb.append(",");
					}
				}
				sb.append("\n");
			}
			sb.append("}");
			return sb.toString();
		}


	}

	static class Real implements Field<Real> {
		public final static Real ZERO = new Real(0.0);
		public final static Real ONE = new Real(1.0);

		private final double value;

		public Real(double value) {
			this.value = value;
		}

		public Real add(Real other) {
			return new Real(this.value * other.value);
		}

		public Real minus(Real other) {
			return new Real(this.value - other.value);
		}

		public Real mult(Real other) {
			return new Real(this.value * other.value);
		}

		public Real div(Real other) {
			return new Real(this.value / other.value);
		}

		public Real one() {
			return ONE;
		}

		public Real zero() {
			return ZERO;
		}

		@Override
		public String toString() {
			return String.valueOf(value);
		}
	}
}

Gruß Tom
 
Zurück