Generics? Covariant return types?

W

Webb Roberts

I'm having trouble ironing out language features in 1.5 to perform some
operations and have them be strongly typed. I'd like to implement
strongly-typed classes derived from a simple base class. It seems like
the result would be a combination of covariant return types, plus a
proper use of <T extends Number>, but I can't seem to get it right.

public abstract class Number {
public abstract Number add(Number number);
}

The derived classes should override add(n), but be strongly typed.
Something that acts like what follows:

public class RealNumber extends Number {
private final double real;
public RealNumber(double real) {
this.real = real;
}
public RealNumber add(RealNumber rhs) {
return new RealNumber(this.real + rhs.real);
}
}

But, obviously, you'd want to be able to do operations in a proper
generic way, like on a Vector<T extends Number>.

Another example, for complex numbers:

public class ComplexNumber extends Number {
private final double real;
private final double imaginary;
public RealNumber(double real, double imaginary) {
this.real = real;
this.imaginary = real;
}
public ComplexNumber add(ComplexNumber rhs) {
return new ComplexNumber(this.real + rhs.real, this.imaginary +
rhs.imaginary);
}
}
 
R

Roedy Green

public class ComplexNumber extends Number {
private final double real;
private final double imaginary;
public RealNumber(double real, double imaginary) {
oops
public ComplexNumber(double real, double imaginary) {
this.real = real;
this.imaginary = real;
}

What threw me off was you use of the name "Number" for your class
which already has meaning in Java.
 
W

Webb Roberts

Yeah, that's a typo in the example. obviously, it's just (wrong)
simple example code. What I need help with is how to form the derived
types (RealNumber, ComplexNumber), so that the add() has the right
form. Any help?

Thanks,
Webb
 
T

Thomas Hawtin

Webb said:
I'm having trouble ironing out language features in 1.5 to perform some
operations and have them be strongly typed. I'd like to implement
strongly-typed classes derived from a simple base class. It seems like
the result would be a combination of covariant return types, plus a
proper use of <T extends Number>, but I can't seem to get it right.

public abstract class Number {
public abstract Number add(Number number);
}

It's generally not a good idea to reuse java.lang class names (or tabs).

You are trying to do much the same a java.lang.Comparable, so as it does
give Number a parameter, Number<T>. If you want to specify a bound, copy
Enum, so Number<N extends Number<N>>.

public abstract class NumberValue<N extends NumberValue<N>> {
public abstract N add(N number);
}

public final class RealNumber extends NumberValue<RealNumber> {
private final double real;
public RealNumber(double real) {
this.real = real;
}
public RealNumber add(RealNumber rhs) {
return new RealNumber(this.real + rhs.real);
}
}

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top