Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Overriding return types

 
Clara Banks
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've got a class called Matrix with a method called transpose that returns type Matrix:

public Matrix transpose() { ... }

Now I have a subclass called Vector that extends Matrix. I want to be able to transpose that as well but return a Vector:

public Vector transpose() {...}

Is this not doable? According to this tutorial, it should be:

Java tutorial from Sun's site

The overriding method has the same name, number and type of arguments, and return value as the method it overrides. (In fact the return type of a subclass can be a subclass of the return type of its superclass.
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
According to the tutorial, it shouldn't be
An instance method in a subclass with the same signature and [B]return type[B] as an instance method in the superclass overrides the superclass's method

[ September 27, 2005: Message edited by: Joanne Neal ]
 
Clara Banks
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Perhaps I misunderstand this statement on that site:

In fact the return type of a subclass can be a subclass of the return type of its superclass.
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry. I didn't read the bit about Vector being a subclass of Matrix. Are you sure that the compiler is not interpreting Vector as being java.util.Vector - a standard Java class ?
 
Edwin Keeton
Ranch Hand
Posts: 214
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can return a Vector, since a Vector is a Matrix by inheritance, but the signature of the overriding transpose() method in Vector must be the same.

 
Clara Banks
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you sure that the compiler is not interpreting Vector as being java.util.Vector - a standard Java class


Yes - I did not import any libraries.



Well, this does compile and run. However, if I try to now pass this to some method that expects a vector, it fails. Even though I returned a vector as you suggested, the method sees a Matrix and won't compile.
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Generally, giving classes names of existing SDK classes is a bad idea, since it leaves you open to errors when you (or your IDE automatically) imports the wrong class. That being said, if your Vector extends Matrix, then it is of the type Matrixa nd can be used in any method which takes a Matrix (or a Vector). Can you show us the code that is causing the error?
 
Julien Grenier
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually if you are using Java 5.0 you can do it.

something like


is working in java 5.0 but not in previous release.
 
Clara Banks
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Generally, giving classes names of existing SDK classes is a bad idea


I'll keep it in mind - didn't realize there was already an existing class.

That being said, if your Vector extends Matrix, then it is of the type Matrixa nd can be used in any method which takes a Matrix (or a Vector). Can you show us the code that is causing the error?


The issue is that I'm trying to override a Matrix method that returns a Matrix into a Vector method that returns a Vector. That seems not possible. If I try the solution mentioned above (make the return type a Matrix but return a Vector), I still get back a Matrix.

Here's some sample code:





Basically, y.test(x) works, but y.text(x.transpose()) does not, as it sees x.transpose() as being a Matrix (even though a vector was returned).
 
Tommy Becker
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You need to cast the result of x.transpose(). Like this:


The reason is that transpose returns a Matrix. This is fine since Vectors are Matrices. But since the test method *requires* a Vector, you have to tell Java that you know what you're doing, and that it should the result of the transpose call as a Vector.

Edit: Forgot some parens.
[ September 27, 2005: Message edited by: Tommy Becker ]
 
Clara Banks
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, but I generally want x.transpose() to always return a vector if x is one, and explicitly casting every time is a pain. But it seems my "ideal" way is not possible.

I'll examine what I'm doing and see if I should bother with inheritance here. I had intended to produce other subclasses of Matrix (symmetric positive definite, banded, etc) in order to save a lot of code typing - all matrices are added and transposed the same way, for example. However, doing these operations require a return type of the same kind as the argument(s) (sometimes).

Perhaps the best way is just to have a single class, and store the fact that they're vectors, SPD's, etc through member variables, and check in each method what type of matrix I'm dealing with if there is supposed to be some different behavior.
[ September 27, 2005: Message edited by: Clara Banks ]
 
Julien Grenier
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you are using JDK 5.0.

You can override the return type with a subclass and do the following
Vector v = x.transpose();

if not you are forced to return the parent class and downcast it (i.e : Vector v = (Vector)x.transpose() .

Julien
 
Tommy Becker
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The reason you can't do exactly what you want is that it would then be trivial to write some code in which it would not be obvious (to the JVM) which of the transpose methods to call.

The casting is a nicer solution than lumping everything in one class IMO. You could make the test method take a Matrix argument and then maybe use some reflection magic to implement different behavior based on the runtime type of the object, I dunno. Good luck.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As already pointed out, this is a feature new in Java 5. It is called "covariant return types", by the way.
 
Clara Banks
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you are using JDK 5.0.


I thoughtthat's what I was running - thought I installed it a few weeks ago.

Turns out I'm using the Blackdown JDK.

I'll go upgrade to the Sun JDK.
 
Clara Banks
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Worked with the new Sun JDK!

(The way I wanted it - transpose method in Vector class now has a return type of Vector).

Thanks, everyone.
 
Consider Paul's rocket mass heater.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic