覆盖接口方法以确保它只能用于相同类型的对象的正确方法是什么?
What is the correct way to override an interface method to ensure that it can only be used on objects of identical types?
我正在 Java 中创建 Matrix
class 以用于线性代数程序。现在它有双打,但我想抽象它。
我创建了一个名为 MatrixElement
的接口,它将包含 add
、multiply
、divide
以及执行这些矩阵运算所需的任何其他算术方法.
这是 Matrix
class 的片段:
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);
}
最后,这是我创建的实现此接口的示例 class:
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
对象可以包含任何一个 class 实现接口 MatrixElement
的实例
MatrixElement
包含矩阵运算所必需的算术方法,如add
- 踢球者:实现
MatrixElement
的 类 只能在相同 class 的其他实例上使用其方法。例如,Fraction
只能添加到其他 Fraction
个实例。两个 classes 可以实现 MatrixElement
、,但它们不一定能够相互添加。
我 运行 这个设计是由另一个程序员设计的,并被告知像这样转换是不好的做法。如果是这样,执行此操作的正确方法是什么?我如何使用具有类似功能的 'group' classes 的接口用于参数化,然后限制可以在子方法中使用所述接口的哪些子接口?
上面post对泛型有两个要求。
Requirement 1: Elements that can be added to other elements of the same type
您想对某些数据类型强加契约,以便这些类型的实例可以添加到相同类型的其他实例,并且只能添加相同类型。目的是支持以下类型的操作:
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
是一个类型,它的实例可以添加到相同类型的其他实例以产生另一个相同类型的实例,这是所需要的。
Requirement 2: Two-dimensional matrices of elements, all of the same type can be added to other two-dimensional matrices of elements of the same type and same dimensions
这个合约可以表示为:
public class Matrix<T extends MatrixElement<T>> {
public Matrix<T> add (Matrix<T> another) { ... }
}
此合同规定 Matrix
由 MatrixElement
类型的元素组成,因此所有元素都属于同一类型。 Matrix
还允许与另一个 Matrix
相加,前提是两者都具有相同类型的元素。结果作为具有相同类型元素的第三个 Matrix
返回。
样品可用 on Github。
我正在 Java 中创建 Matrix
class 以用于线性代数程序。现在它有双打,但我想抽象它。
我创建了一个名为 MatrixElement
的接口,它将包含 add
、multiply
、divide
以及执行这些矩阵运算所需的任何其他算术方法.
这是 Matrix
class 的片段:
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);
}
最后,这是我创建的实现此接口的示例 class:
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
对象可以包含任何一个 class 实现接口MatrixElement
的实例
MatrixElement
包含矩阵运算所必需的算术方法,如add
- 踢球者:实现
MatrixElement
的 类 只能在相同 class 的其他实例上使用其方法。例如,Fraction
只能添加到其他Fraction
个实例。两个 classes 可以实现MatrixElement
、,但它们不一定能够相互添加。
我 运行 这个设计是由另一个程序员设计的,并被告知像这样转换是不好的做法。如果是这样,执行此操作的正确方法是什么?我如何使用具有类似功能的 'group' classes 的接口用于参数化,然后限制可以在子方法中使用所述接口的哪些子接口?
上面post对泛型有两个要求。
Requirement 1: Elements that can be added to other elements of the same type
您想对某些数据类型强加契约,以便这些类型的实例可以添加到相同类型的其他实例,并且只能添加相同类型。目的是支持以下类型的操作:
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
是一个类型,它的实例可以添加到相同类型的其他实例以产生另一个相同类型的实例,这是所需要的。
Requirement 2: Two-dimensional matrices of elements, all of the same type can be added to other two-dimensional matrices of elements of the same type and same dimensions
这个合约可以表示为:
public class Matrix<T extends MatrixElement<T>> {
public Matrix<T> add (Matrix<T> another) { ... }
}
此合同规定 Matrix
由 MatrixElement
类型的元素组成,因此所有元素都属于同一类型。 Matrix
还允许与另一个 Matrix
相加,前提是两者都具有相同类型的元素。结果作为具有相同类型元素的第三个 Matrix
返回。
样品可用 on Github。