Folks, this seems like it should be straightforward, but I’m drawing a blank here.
As a simplified example, consider an abstract class called Number with an abstract method add(). I want to create two concrete subclasses, Integer and Float, with method signatures Integer.add(Integer other) and Float.add(Float other). A Float can NOT be added to an Integer. What should the method signature of the abstract add() method in the Number class be in order to enforce this constraint at compile-time?
3
Number
should not have an add()
method.
Declaring a method in a base class (Or in an interface, for that matter), is a promise to implement this method. If your base class has add(Integer i)
, that’s a promise that each instance of Number
– be it a Float
or an Integer
– will have that method.
You can use generics, as jozefg commented – but then your two classes do not share a common superclass: Integer extends Number<Integer>
, and Float extends Number<Float>
. These are two different classes, that share their code. At runtime (In Java), erasure makes it look like it’s the same class, but that’s a technicality; When it comes to static (compile-time) terms, the two classes are distinct.
Another dynamic solution is to have Number
define either add(Number)
, or both add(Integer)
and add(Float)
, and throw an exception when the wrong method is invoked; This is certainly not what you’re after, and is not generally considered a good use of Object-Oriented features.
2