Sadashiv
Sadashiv

Reputation: 437

Why java does not allow to change return type in case of method overriding

I have class A as:

 public class A {
    int sayHello(int i,int j){
        return i+j;
    }
 }

Another class B as:

public class B extends A {  
    @Override
    int sayHello(int i, int j) {
        return i+j;
    }
}

If I change return type of method sayHello(int,int) of class A from int to float it shows an error because as per the overriding rule return types are also considered thats why it is not a valid overriding and overloading also.

I am confuse with why java does not allow to change returntype. why return types also needs to be same

Upvotes: 2

Views: 4834

Answers (4)

Andy Turner
Andy Turner

Reputation: 140319

You can change the return type when you override the method: it just has to be overridden with a covariant type.

For example, if you define an interface like:

interface Foo {
  Object foo();
}

then it is fine to implement it thus:

class Bar implements Foo {
  @Override public String foo() {
    return "";
  }
}

because all implementations of Foo.foo() must return an Object, and all Strings are Objects.

However, you couldn't do it the other way round: if the return type of Foo.foo() were String, you couldn't implement it to return an Object, because callers of the method need to be able to invoke String's methods on that instance. For instance:

void test(Foo instance) {
  System.out.println(instance.foo().length());
}

This wouldn't work at runtime if an Object were returned, as there is no length() method on an Object. (But more specifically, it must be the String.length() method, not just any length method: Java does not support duck typing). The compiler can detect this mismatch, and so it stops you doing it.

There are no types covariant with int (or any primitive type, for that matter), so you have to return an int when you override a method which returns int.


The theoretical reason why this is allowable is the Liskov Substitution Principle, which can be paraphrased as "subtype methods can be more general in the parameters they accept, and more specific in the types they return".

Java doesn't allow more general parameter types to be used, however, because of the way it resolves method overloads.

Upvotes: 2

Mike Robinson
Mike Robinson

Reputation: 8945

Basically, Java considers this (very correctly, I think ...) to be a nasty-bug(!) that it just helpfully caught for you at compile time.

The essential idea behind descendent-classes and overrides is that callers need not be concerned as to which “flavor” of a particular class-instance they might be dealing with, as long as it is known that it is an instance of that class or one of its descendants.   The compiler can also generate reliable code, because although the underlying implementation of a particular class might vary, the prototype does not:   each instance will have the same methods, a-n-d, will return the same data types.

If you need to special-case return a different data type, you should define a custom method to do so.   This will also(!) be important for the various Programmers Who Will Follow You.   (“Too bad about that bread-truck ...” etc.)   If your code does something different, it should very-noticeably look different in the application source-code!

Remember:   if Java actually allowed you to do this sort of thing, you might unwittingly introduce nas-s-s-s-ssty bugs in any piece of existing, “debugged,” code, anywhere(!) in your undoubtedly-vast application, that happened to stumble-upon an instance of “your special-case.”

Upvotes: 0

npinti
npinti

Reputation: 52185

As illustrated here (emphasis my own)

The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type.

If the return type is not the same, it will break things for other classes which could use polymorphism to detect the type of the class at runtime.

Upvotes: 0

tkausl
tkausl

Reputation: 14269

Because:

class Parent {
    int method() { return 1; }
}

class Child extends Parent {
    float method() { return 1.0f; }
}

Parent p = new Child();
int myInt = p.method();

What does method() return? It should be an int, because Parent says it's an int. But Child returns an float. So what do you expect to happen? Should the JVM just crash?

By the way, you can change the return-type, but it has to be a subtype of the type, the overridden method returns. So you could override a method which returns a Parent and use Child as return-type.

Upvotes: 7

Related Questions