Je crée une classe Matrix
en Java pour l'utiliser dans un programme d'algèbre linéaire. En ce moment, il détient des doubles, mais je veux l'abstraire.Quelle est la bonne façon de remplacer une méthode d'interface pour s'assurer qu'elle ne peut être utilisée que sur des objets de types identiques?
J'ai créé une interface appelée MatrixElement
, qui contiendra add
, multiply
, divide
, et toute autre méthode arithmétique nécessaires pour effectuer ces opérations de la matrice.
Voici un extrait de la Matrix
classe:
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);
}
}
Voici comment les méthodes sont déclarées dans MatrixElement
public interface MatrixElement {
public MatrixElement add(MatrixElement e);
}
Enfin, voici une classe d'exemple que j'ai créé qui implémente cette interface:
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;
}
}
L'idée principale ici est la suivante:
- objets
Matrix
peuvent contenir des instances de toute une classe qui implémente l'interfaceMatrixElement
MatrixElement
contient des méthodes arithmétiques nécessaires pour la manipulation de la matrice, commeadd
- Le botteur: Les classes qui implémentent
MatrixElement
ne peut utiliser ses méthodes sur d'autres instances de la même classe. Par exemple,Fraction
peut uniquement être ajouté à d'autres instancesFraction
. Deux classes peuvent implémenterMatrixElement
, mais elles ne devraient pas nécessairement pouvoir s'ajouter les unes aux autres.
J'ai exécuté cette conception par un autre programmeur et on m'a dit que le lancer comme ceci est une mauvaise pratique. Si oui, quelle est la bonne façon de le faire? Comment puis-je utiliser une interface pour regrouper des classes ayant des fonctionnalités similaires à celles du paramétrage, mais restreindre les enfants de cette interface qui peuvent être utilisés dans les méthodes des enfants?
'nouveau T()' ne compilera pas –
'public static Matrix somme (matrice a, matrice b)' –
@Lashane @ElliotFrisch vous remercie d'avoir ceux sur. Je n'ai pas encore écrit la version générique de 'Matrix', donc j'attends quelques erreurs de syntaxe. Cette pièce a été principalement fournie pour donner un contexte. Ma question est dans l'implémentation de l'interface 'MatrixElement' – user3043902