Tru
Tru

Reputation: 1467

How to implement an overriden method with a different return type?

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

Answers (6)

Siva Kumar Reddy G
Siva Kumar Reddy G

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

A.H.
A.H.

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

JB Nizet
JB Nizet

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

Peter Lawrey
Peter Lawrey

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

Matthew Adams
Matthew Adams

Reputation: 10126

"is this a seriously bad example of OO design" Yep. You can't do it.

Upvotes: 7

Pablo Santa Cruz
Pablo Santa Cruz

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

Related Questions