4

I'm trying to create a matrix library (educational purpose) and have reached an obstacle I'm not sure how to approach with grace. Adding two matrices is a simple task, using a method get() on each each matrices' elements individually.

However, the syntax I've used is wrong. NetBeans claims it's expecting a class, but found a type parameter; to me, a type parameter is just a set with 1:1 mapping to the set of classes.

Why am I wrong here? I've never seen a type parameter be anything else than a class before, so shouldn't the following bit imply M to be a class?

M extends Matrix

public abstract class Matrix<T extends Number, M extends Matrix>
{
    private int rows, cols;
    public Matrix(int rows, int cols)
    {
        this.rows = rows;
        this.cols = cols;
    }

    public M plus(Matrix other)
    {
        // Do some maths using get() on implicit and explicit arguments.
        // Store result in a new matrix of the same type as the implicit argument,
        // using set() on a new matrix.
        M result = new M(2, 2); /* Example */
    }

    public abstract T get(int row, int col);
    public abstract void set(int row, int col, T val);
}
B. Lee
  • 191
  • 6
  • 1
    Why does the Matrix class have a type that extends itself? – OneCricketeer Mar 30 '16 at 20:25
  • @cricket_007 My reasoning is that the function plus() should return an object whose class extends Matrix. It sounds really silly now that I type it out. Maybe the return type should just be Matrix.. But then I can't instantiate a matrix inside the plus() function, right? As it's an abstract class. – B. Lee Mar 30 '16 at 20:28
  • 2
    You cannot instantiate a type parameter `M` directly because you don't know its exact type. – Andrew Tobilko Mar 30 '16 at 20:28
  • Correct, you can't instantiate an abstract class, but you also can't directly instantiate a type either. Do you plan on returning a Matrix other than the T type? – OneCricketeer Mar 30 '16 at 20:30
  • 1
    I suggest thinking about creating `public abstract M plus(M other);` and its implementation in the subclasses – Andrew Tobilko Mar 30 '16 at 20:35
  • I think @AndrewTobilko has given the *best* solution yet. I was hoping to avoid this way, as this means I have to create this method in all matrix implementation, even though they are identical, except for what matrix type is returned. No methods outside of Matrix abstract class type is used in plus(). – B. Lee Mar 30 '16 at 20:38

4 Answers4

2

You cannot instantiate a type parameter M directly because you don't know its exact type.


I suggest thinking about creating the following method

public abstract <M extends Matrix> M plus(M other); 

and its implementation in the subclass.

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
2

From your code, I guess you want to extends some child class from Matrix and do calculation on them.

Change to

public abstract class Matrix<T extends number> {
  ...
  public abstract Matrix plus(Matrix other);
  ...
}

In each child class, add implementation of plus. Because of the construction function of child class is defined there.

Tao
  • 21
  • 4
0

I don't think your M is necessary.

If M is a subclass of Matrix, then just use Matrix in your definition.

public abstract class Matrix<T extends Number>
{
    private int rows, cols;
    public Matrix(int rows, int cols)
    {
        this.rows = rows;
        this.cols = cols;
    }

    public Matrix<T> plus(Matrix<T> other)
    {
    }

    public abstract T get(int row, int col);
    public abstract void set(int row, int col, T val);
}
lkq
  • 2,326
  • 1
  • 12
  • 22
0

The following code is wrong:

 M result = new M(2, 2);

M is not a class that you can instantiate.

Basically, you need to change your data structure a bit, because your Matrix class is abstract and can't be instantiated either!

I suggest you to change the return type of plus to Matrix and leave it abstract.

Ali Hashemi
  • 3,158
  • 3
  • 34
  • 48