Reputation: 1467
Consider the situation where I have an abstract class in Java;
public abstract class Foo
{
public abstract int myOperation();
}
Now, some of its subclasses may override myOperation like this;
class A extends Foo
{
public int myOperation()
{
// Do stuff
}
}
But if one subclass instead wants to return some other data type like;
class A extends Foo
{
public Object myOperation()
{
// Do stuff
}
}
I want the method name to be the same, to keep the design intact so that the clients don't necessarily select which method to call. Is there a workaround for this other than having separate methods with one being an empty implementation or using Object as the return type? Or is this a seriously bad example of OO design?
I've heard about Covariant return types in C++ and wondering whether Java has some other mechanism for this.
I'm also free to use an interface here.
Upvotes: 4
Views: 502
Reputation: 1274
You can have different data types, when you use return type as derived i.e,Co-varients. when you use primitive data type, you cannot change it.
If Super class method is any derived data type, while over ridding in the sub-class return type can be same derived data type or sub-class derived data type.
Upvotes: 3
Reputation: 66263
You cannot do this, because it would break the contract of Foo
.
A a = new A();
someUtilityMethod(a);
...
void someUtilityMethod(Foo foo){
int i = foo.myOperation(); // This would break
}
This principle is called Liskov substitution principle and it is the foundation upon which OO is built.
Upvotes: 2
Reputation: 691735
This is not possible, because the method, declared in the abstract class, defines a contract: it returns an int. This contract must be respected by all implementations. What would happen if you did:
Foo foo = new A();
int i = foo.myOperation();
It would break, because myOperation would not return an int
. That's why it's not allowed.
What is allowed, though, is the following:
public abstract class Foo {
public abstract Object myOperation();
}
public class A extends Foo {
@Override
public String myOperation() {
return "some string";
}
}
In this case, the contract is respected. The method must return an Object, it returns a String, and a String is an Object.
Upvotes: 2
Reputation: 533520
Java has co-variant return types but the return type must be more specific, not less specific. If a method in a parent class return int
then all its sub-type must do as well otherwise the caller of such a method doesn't really know what type it is getting.
Foo foo = new A()
int i = foo.method();
If method() returns anything but int
this statement no longer makes sense.
When you can do is if the method in the super class return Object
and a dervice class return Number
then the sub-class of both can return Integer
Upvotes: 5
Reputation: 10126
"is this a seriously bad example of OO design" Yep. You can't do it.
Upvotes: 7
Reputation: 181280
You can't. Neither using inheritance, nor using an interface for this. It's going to be a compiler error so you won't be able to run your program at all.
You could return java.lang.Object
and return whatever object you want. In case you need to return a primitive, you could return its object wrapper.
Upvotes: 8