One of the most annoying features when you're using Java inheritance is the inability to override return types. This is most commonly desired when you've got a base class, and then a subclass adds a dimension (either literally or figuratively) to the base class. Typically, you're unable to return that extra dimension without defining a new method (and new name), since the method that the base class used probably had a narrower return type. Thankfully, you can solve this problem using Tiger.
Example 1-4 is a simple class hierarchy that demonstrates overriding the return type of a superclass's method.
NOTE
Keep in mind that none of this code compiles under Java 1.4, or even in Tiger without the "-source 1.5" switch
class Point2D { protected int x, y; public Point2D( ) { this.x=0; this.y=0; } public Point2D(int x, int y) { this.x = x; this.y = y; } } class Point3D extends Point2D { protected int z; public Point3D(int x, int y) { this(x, y, 0); } public Point3D(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } } class Position2D { Point2D location; public Position2D( ) { this.location = new Point2D( ); } public Position2D(int x, int y) { this.location = new Point2D(x, y); } public Point2D getLocation( ) { return location; } } class Position3D extends Position2D { Point3D location; public Position3D(int x, int y, int z) { this.location = new Point3D(x, y, z); } public Point3D getLocation( ) { return location; } }
The key is the line public Point3D getLocation( ), which probably looks pretty odd to you, but get used to it. This is called a covariant return, and is only allowed if the return type of the subclass is an extension of the return type of the superclass. In this case, this is satisfied by Point3D extending Point2D. It's accomplished through the annotation, covered in detail in Chapter 6.