By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,468 Members | 1,859 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,468 IT Pros & Developers. It's quick & easy.

overriding methods with a different return type

P: n/a
so i have a situation that i know cannot be solved directly, and i've
already worked around it, but i was hoping to find an explanation as to
why this behavior is as it is... i have an abstract class:

public abstract class Function
{
public abstract Number evaluate(Number parameter);
}

and i have a descendant of that class:

public class IntegerFunction extends Function
{
public Integer evaluate(Number parameter)
{
/* insert code here */
}
}

but this doesn't compile. i cannot override the superclass evaluate()
with the subclass evaluate() becuase of the different return types... even
though Integer is a Number.

my problem is this... i cannot envision a bad situation happening if this
were allowed.

let's say i write a program using the abstract class to keep it portable
and general:

Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Number y = f(x);

in my mind, i believe this works great. why? because i can change the
function f to say a different function that still guarantees its return
value is some form of Number, and it makes sense.

but, at the same time, some programs are better written to take direct
advantage of a specific return type, so i'd like to keep IntegerFunction's
evaluate method returning type Integer only.

it seems like the policy that doesn't allow me to compile these two
classes as they are doesn't help prevent any problems, and instead limits
the programmer a bit.

can someone shed some light as to why this is the way it is? (in
particular, maybe give an easy example that can illustrate a problem that
can occur if my code was allowed to be compiled correctly...)

thanks!

murat

--
Murat Tasan
mx**@po.cwru.edu
ta***@eecs.cwru.edu
mu*********@cwru.edu
http://genomics.cwru.edu

Jul 17 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Murat Tasan wrote:
so i have a situation that i know cannot be solved directly, and i've
already worked around it, but i was hoping to find an explanation as to
why this behavior is as it is... i have an abstract class:

public abstract class Function
{
public abstract Number evaluate(Number parameter);
}

and i have a descendant of that class:

public class IntegerFunction extends Function
{
public Integer evaluate(Number parameter)
{
/* insert code here */
}
}

but this doesn't compile. i cannot override the superclass evaluate()
with the subclass evaluate() becuase of the different return types... even
though Integer is a Number.

my problem is this... i cannot envision a bad situation happening if this
were allowed.

let's say i write a program using the abstract class to keep it portable
and general:

Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Number y = f(x);

in my mind, i believe this works great. why? because i can change the
function f to say a different function that still guarantees its return
value is some form of Number, and it makes sense.

but, at the same time, some programs are better written to take direct
advantage of a specific return type, so i'd like to keep IntegerFunction's
evaluate method returning type Integer only.

it seems like the policy that doesn't allow me to compile these two
classes as they are doesn't help prevent any problems, and instead limits
the programmer a bit.

can someone shed some light as to why this is the way it is? (in
particular, maybe give an easy example that can illustrate a problem that
can occur if my code was allowed to be compiled correctly...)

thanks!

murat

an Integer is a Number, you're right about that. But you can't change
the return type. You _can_ still return an Integer, but you'll have to
cast it to an Integer if you really want to use it as an Integer.
Using your example:

public abstract class Function
{
public abstract Number evaluate(Number parameter);
}
public class IntegerFunction extends Function
{
public Number evaluate(Number parameter)
{
/* insert code here */
Integer i = new Integer(0);
return i;
}
}
Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Number y = f.evalate(x);

Nothing changes (ie this is what you said you wanted to do)... you just
have to fix your return type in IntegerFunction.

However this won't compile,
Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Integer y = f.evalate(x);

but you can do this:

Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Number y = f.evalate(x);
if(y instanceof Integer) {
Integer z = (Integer)y;
}
But really, this is almost a moot point because Number has intValue(),
floatValue(), longValue(), doubleValue(), byteValue(), shortValue() in
it anyway.

-Bryan

Jul 17 '05 #2

P: n/a
yeah, that is basically what i've done, but it still doesn't make sense to
me.

if i'm a programmer and i want to use the abstract class, i'll receive a
Number as the return value, but if i want to use a specific subclass, i
should be able to be more specific about what return value i receive, and
that subclass should basically define it's return type for me: Integer.

p.s. i know about the typeValue() methods of Number, but the general
problem lingers in many other situations.

it just kinda seems like a design oversight in the java language, as i
still cannot envision a problem occuring from what i'd like to do.

oh well... maybe i should look at c#...

murat

On Thu, 13 Nov 2003, Bryan Boone wrote:
Murat Tasan wrote:
so i have a situation that i know cannot be solved directly, and i've
already worked around it, but i was hoping to find an explanation as to
why this behavior is as it is... i have an abstract class:

public abstract class Function
{
public abstract Number evaluate(Number parameter);
}

and i have a descendant of that class:

public class IntegerFunction extends Function
{
public Integer evaluate(Number parameter)
{
/* insert code here */
}
}

but this doesn't compile. i cannot override the superclass evaluate()
with the subclass evaluate() becuase of the different return types... even
though Integer is a Number.

my problem is this... i cannot envision a bad situation happening if this
were allowed.

let's say i write a program using the abstract class to keep it portable
and general:

Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Number y = f(x);

in my mind, i believe this works great. why? because i can change the
function f to say a different function that still guarantees its return
value is some form of Number, and it makes sense.

but, at the same time, some programs are better written to take direct
advantage of a specific return type, so i'd like to keep IntegerFunction's
evaluate method returning type Integer only.

it seems like the policy that doesn't allow me to compile these two
classes as they are doesn't help prevent any problems, and instead limits
the programmer a bit.

can someone shed some light as to why this is the way it is? (in
particular, maybe give an easy example that can illustrate a problem that
can occur if my code was allowed to be compiled correctly...)

thanks!

murat

an Integer is a Number, you're right about that. But you can't change
the return type. You _can_ still return an Integer, but you'll have to
cast it to an Integer if you really want to use it as an Integer.
Using your example:

public abstract class Function
{
public abstract Number evaluate(Number parameter);
}
public class IntegerFunction extends Function
{
public Number evaluate(Number parameter)
{
/* insert code here */
Integer i = new Integer(0);
return i;
}
}
Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Number y = f.evalate(x);

Nothing changes (ie this is what you said you wanted to do)... you just
have to fix your return type in IntegerFunction.

However this won't compile,
Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Integer y = f.evalate(x);

but you can do this:

Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Number y = f.evalate(x);
if(y instanceof Integer) {
Integer z = (Integer)y;
}
But really, this is almost a moot point because Number has intValue(),
floatValue(), longValue(), doubleValue(), byteValue(), shortValue() in
it anyway.

-Bryan


--
Murat Tasan
mx**@po.cwru.edu
ta***@eecs.cwru.edu
mu*********@cwru.edu
http://genomics.cwru.edu

Jul 17 '05 #3

P: n/a
Read up on java 1.5. What you describe is usually referred to as "covariant
return types" and it is supported in 1.5 along with all kinds of other
extensions of the type system.

Silvio Bierman
Jul 17 '05 #4

P: n/a
jb
Why not return an interface, and have the return type implement them?

Murat Tasan <ta***@eecs.cwru.edu> wrote in message news:<Pine.SOL.4.53.0311122243580.2354@homer>...
so i have a situation that i know cannot be solved directly, and i've
already worked around it, but i was hoping to find an explanation as to
why this behavior is as it is... i have an abstract class:

public abstract class Function
{
public abstract Number evaluate(Number parameter);
}

and i have a descendant of that class:

public class IntegerFunction extends Function
{
public Integer evaluate(Number parameter)
{
/* insert code here */
}
}

but this doesn't compile. i cannot override the superclass evaluate()
with the subclass evaluate() becuase of the different return types... even
though Integer is a Number.

my problem is this... i cannot envision a bad situation happening if this
were allowed.

let's say i write a program using the abstract class to keep it portable
and general:

Function f = Class.forName(IntegerFunction).newInstance();
Number x = new Integer(10);
Number y = f(x);

in my mind, i believe this works great. why? because i can change the
function f to say a different function that still guarantees its return
value is some form of Number, and it makes sense.

but, at the same time, some programs are better written to take direct
advantage of a specific return type, so i'd like to keep IntegerFunction's
evaluate method returning type Integer only.

it seems like the policy that doesn't allow me to compile these two
classes as they are doesn't help prevent any problems, and instead limits
the programmer a bit.

can someone shed some light as to why this is the way it is? (in
particular, maybe give an easy example that can illustrate a problem that
can occur if my code was allowed to be compiled correctly...)

thanks!

murat

Jul 17 '05 #5

P: n/a
so i have a situation that i know cannot be solved directly, and i've
already worked around it, but i was hoping to find an explanation as to
why this behavior is as it is... i have an abstract class:

public abstract class Function
{
public abstract Number evaluate(Number parameter);
}

and i have a descendant of that class:

public class IntegerFunction extends Function
{
public Integer evaluate(Number parameter)
{
/* insert code here */
}
}

but this doesn't compile. i cannot override the superclass evaluate()
with the subclass evaluate() becuase of the different return types... even
though Integer is a Number.

my problem is this... i cannot envision a bad situation happening if this
were allowed.


And you are right. It would be safe to allow overriding methods to
return a more precise type. I think it's just Sun being conservative on
this issue.

BTW, it looks like you want a Java-like language that supports first
class functions, so you should really try Nice: http://nice.sf.net :-)
Then you could write Number->Number and Number->int, and you could use a
value of type Number->int where Number->Number is expected.

Cheers,

Daniel

Jul 17 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.