Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java- How do I gather classes by using enum?

Tags:

java

Let's assume that I have lots of implementations of matrices (Which don't extend from one to another) and I want the user to be able to see all the different classes, to gather them in some kind of enum or something, How can I do that? It doesn't have to be a menu or something, just so I will be able to see all the classes, just like enum.

For example:

MainMatrix matrix= new (ALL THE POSSIBILITIES)();

While the MainMatrix is the common interface of all matrices.

Can I use enum that will create instance of new class matching the option I'll choose? for example:

public enum Matrices{
DIAGONAL_MATRIX(new DiagonalMatrix());
..
..
}

Can I do that?

like image 600
Numerator Avatar asked Mar 19 '26 10:03

Numerator


1 Answers

Here a solution using an enum with an abstract method:

public enum MatrixFactory {

    /**
     * Creates a diagonal matrix
     * 
     * args[0] : a double[] with the diagonal values
     */
    DIAGONAL_MATRIX {
        @Override
        public MainMatrix create(Object[] args) {
            double[] diagonal = (double[]) args[0];
            return new DiagonalMatrix(diagonal);
        }
    },

    /**
     * Creates a full matrix
     * 
     * args[0] : the number of rows
     * 
     * args[1] : the number of columns
     */
    FULL_MATRIX() {
        @Override
        public MainMatrix create(Object[] args) {
            int rows = (Integer) args[0];
            int cols = (Integer) args[1];
            return new FullMatrix(rows, cols);
        }
    };

    public abstract MainMatrix create(Object[] args);
}

Usage:

MatrixFactory.DIAGONAL_MATRIX.create(new Object[] {new double[] {1.0, 2.0, 3.0}});
MatrixFactory.FULL_MATRIX.create(new Object[] {4, 4});

See also the classic enum tutorial which illustrates this with an arithmetic enum:

public enum Operation {
  PLUS   { double eval(double x, double y) { return x + y; } },
  MINUS  { double eval(double x, double y) { return x - y; } },
  TIMES  { double eval(double x, double y) { return x * y; } },
  DIVIDE { double eval(double x, double y) { return x / y; } };

  // Do arithmetic op represented by this constant
  abstract double eval(double x, double y);
}

I advocate a regular factory though, because the usage is much clearer. Using an enum does not add any benefits I can think of in this context.

public class MatrixFactory {

    /**
     * Creates a diagonal matrix
     * 
     * @param diagonal the diagonal values
     * @return
     */
    public static MainMatrix diagonalMatrix(double[] diagonal) {
        return new DiagonalMatrix(diagonal);
    }

    /**
     * Creates a full matrix
     * 
     * @param rows the number of rows
     * @param cols the number of columns
     * @return
     */
    public static MainMatrix fullMatrix(int rows, int cols) {
        return new FullMatrix(rows, cols);
    }
}

Usage:

MatrixFactory.diagonalMatrix(new double[] {1.0, 2.0, 3.0});
MatrixFactory.fullMatrix(4, 4);
like image 95
Adriaan Koster Avatar answered Mar 22 '26 04:03

Adriaan Koster