1

I currently have an interface Ring that specifies methods like add, multiply, and so on. Thus, I can make a class of vectors whose elements are of type E that has an addition method, a dot product, etc. as long as E extends Ring. For example, a very simple class might look like

public class Vector<E extends Ring<E>> {

     List<E> data;

     public Vector() {
          // constructor implementation here
     }

     public E dot(Vector<E> other) {
          // initialize ``result" somehow
          for (int index=0; index<data.size(); index++) {
              result.add(data.get(index).multiply(other.get(index)));
          }
          return result;
     }

}

In this simple example, one could simply initialize the result as data.get(0).multiply(other.get(0)) and then start the for loop at 1, but I'd like to know if there is a way to specify that there is a ``zero element" of type E.

Ideally, I'd like to specify that E has a static method called zero() so that the zero element is just E.zero(). I can't seem to figure out a way to do this. On the other hand, I can't just add a zero() method to the Ring interface because then I would have to do something like (new E()).zero(), and of course a generic constructor cannot be made in that way. There is a silly shortcut involving something like E zero = data.get(0).zero(), but this does not seem very nice and only works if I already have another instance of an element of type E floating around (which may not be the case in another context). So, is there any nice way to specify the existence of such a zero element that is guaranteed to be implemented in any class E that extends Ring?

Sam
  • 13
  • 2
  • possible duplicate of [Why can't I define a static method in a Java interface?](http://stackoverflow.com/questions/512877/why-cant-i-define-a-static-method-in-a-java-interface) – merlin2011 Dec 14 '14 at 21:56
  • Out of curiosity, why wouldn't the default constructor construct the zero of the ring? – Aaryn Tonita Dec 14 '14 at 22:23
  • @AarynTonita If I define a ring element of type BigFraction (based on a BigInteger numerator and a BigInteger denominator), then would the default be 0? My understanding is that they would be initialized to null. – Sam Dec 14 '14 at 22:38
  • Yes, but I am trying to suggest that you enforce (as a design of your code) the contract that the default constructor actually construct the zero of the group? This means whoever implements a group would need to actually implement the constructor if the group is not trivial, but principle of least surprise implies your default constructor shouldn't construct something like NaN. – Aaryn Tonita Dec 14 '14 at 22:43
  • @AarynTonita That would work for me, in theory, but I wasn't aware that one could enforce a contract on constructors using a Java interface. Would you kindly explain what you mean by this? – Sam Dec 14 '14 at 22:47
  • I'm sorry, I just realized that this won't work because of type erasure: you won't be able to instantiate an element. There should be a decent way to design your Ring algebra, but I am not seeing it. – Aaryn Tonita Dec 14 '14 at 23:32

1 Answers1

0

You can't require implementing classes have a static method. I suggest you not reuse a common builtin class name like Vector as it leads to confusion.

If you have a non-trivial requirement for construction I suggest you use a Factory method to create your instance. In your case you can specify that E have a method zero() even though it is not static. The problem is you have to pass the class, or an instance of that class as an argument. A method/constructor doesn't know what generics you used when you called it and they have to be parameters.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Ah, yes, the Vector class was just an example for this post. Really, what I want to do is to add a determinant method to a class that represents a sparse matrix of type E. Since a sparse matrix only keeps track of nonzero entries, how would one indicate that the determinant of a matrix consisting only of zeros (ie. an ``empty" sparse matrix) is zero? In this case, there would be no objects on which to call the zero() method. – Sam Dec 14 '14 at 22:41
  • You could have a `ZeroProvider` interface which gives you the zero() object for that class. You can use an Enum to implement it. – Peter Lawrey Dec 15 '14 at 03:37