我在Java中创建一个Matrix
类,用于线性代数程序。现在它拥有双打,但我想抽象它。
我创建了一个名为MatrixElement
的接口,其中包含add
,multiply
,divide
以及执行这些矩阵运算所需的任何其他算术方法。< / p>
以下是Matrix
类的摘录:
public class Matrix<T extends MatrixElement> {
private ArrayList<ArrayList<T>> rows;
public Matrix(int numRows, int numCols) {
if (numRows <= 0) {
throw new IllegalArgumentException("Matrix must have at least one row.");
}
if (numCols <= 0) {
throw new IllegalArgumentException("Matrix must have at least one column.");
}
this.rows = new ArrayList<ArrayList<T>>();
for (int r = 0; r < numRows; r++) {
ArrayList<T> row = new ArrayList<T>();
for (int c = 0; c < numCols; c++) {
row.add(new T());
}
this.rows.add(row);
}
}
/* lots of methods omitted */
public static Matrix sum(Matrix a, Matrix b) {
if (a.numRows() != b.numRows() || a.numCols() != b.numCols()) {
throw new IllegalArgumentException("Matrices must be the same size.");
}
Matrix sum = new Matrix(a.numRows(), b.numCols());
for (int r = 1; r <= b.numRows(); r++) {
for (int c = 1; c <= b.numCols(); c++) {
sum.setEntry(r, c, a.getEntry(r, c).add(b.getEntry(r, c)));
}
}
return sum;
}
public Matrix add(Matrix matrix) {
return Matrix.sum(this, matrix);
}
}
以下是MatrixElement
public interface MatrixElement {
public MatrixElement add(MatrixElement e);
}
最后,这是我创建的实现此接口的示例类:
public class Fraction implements MatrixElement {
private BigInteger numerator;
private BigInteger denominator;
public Fraction(int num, int denom) {
numerator = BigInteger.valueOf(num);
denominator = BigInteger.valueOf(denom);
}
@Override
public Fraction add(MatrixElement e) {
Fraction f;
try {
f = (Fraction) e;
} catch (ClassCastException cce) {
throw new IllegalMatrixOperationException("Cannot add " + this.getClass().toString() + " and " + e.getClass().toString());
}
/* addition code omitted */
return this;
}
}
这里的主要想法是:
Matrix
个对象可以保存任何一个实现接口MatrixElement
MatrixElement
包含矩阵操作所需的算术方法,例如add
MatrixElement
的类只能在同一个类的其他实例上使用它的方法。例如,Fraction
只能添加到其他Fraction
实例中。两个类可以实现MatrixElement
,,但它们不一定能够相互添加。 我是由另一位程序员运行这个设计,并被告知像这样的演员是不好的做法。如果是这样,这样做的正确方法是什么?我如何使用一个接口来“分组”具有类似功能的类,以便在参数化中使用,但是然后限制所述接口的哪些子节点可以用在子节点的方法中?
答案 0 :(得分:0)
上述帖子中对泛型有两个要求。
要求1 :可以添加到同一类型的其他元素的元素
您希望对某些数据类型强加合同,以便可以将这些类型的实例添加到同一类型的其他实例中,并且仅添加相同类型。目的是支持以下类型的操作:
int + int = int
long + long = long
real fraction + real fraction = real fraction
complex number + complex number = complex number
本合同可表述如下:
public interface MatrixElement<T> {
T add(T e);
}
用简单的语言来说,这个契约说MatrixElement
是一种类型,其实例可以添加到同一类型的其他实例中,以产生另一个相同类型的实例,这就是所需要的。
要求2 :所有相同类型的元素的二维矩阵可以添加到相同类型和相同维度的元素的其他二维矩阵中
本合同可表示为:
public class Matrix<T extends MatrixElement<T>> {
public Matrix<T> add (Matrix<T> another) { ... }
}
此合约表示Matrix
由MatrixElement
类型的元素组成,因此所有元素都属于同一类型。 Matrix
还允许添加另一个Matrix
,前提是它们都具有相同类型的元素。结果将作为第三个Matrix
返回,其中包含相同类型的元素。
示例可用on Github。