覆盖接口方法以确保它只能用于相同类型的对象的正确方法是什么?

时间:2017-05-15 04:05:00

标签: java oop interface method-overriding parameterization

我在Java中创建一个Matrix类,用于线性代数程序。现在它拥有双打,但我想抽象它。

我创建了一个名为MatrixElement的接口,其中包含addmultiplydivide以及执行这些矩阵运算所需的任何其他算术方法。< / 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,但它们不一定能够相互添加。

我是由另一位程序员运行这个设计,并被告知像这样的演员是不好的做法。如果是这样,这样做的正确方法是什么?我如何使用一个接口来“分组”具有类似功能的类,以便在参数化中使用,但是然后限制所述接口的哪些子节点可以用在子节点的方法中?

1 个答案:

答案 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) { ... }
}

此合约表示MatrixMatrixElement类型的元素组成,因此所有元素都属于同一类型。 Matrix还允许添加另一个Matrix,前提是它们都具有相同类型的元素。结果将作为第三个Matrix返回,其中包含相同类型的元素。

示例可用on Github