Can overridden methods differ in return type?
Asked Answered
M

12

181

Can overridden methods have different return types?

Matchlock answered 4/2, 2013 at 20:17 Comment(1)
If you don't have the same or narrower return type then you will get :: error: method() in subclass cannot override method() in superclassShaeshaef
I
223

Java supports* covariant return types when overriding methods. An overriding method may have a more specific return type than the method being overridden. That is, as long as the new method's return type is assignable to the return type of the method it overrides, it's allowed.

For example:

class ShapeBuilder {
    ...
    public Shape build() {
    ....
}

class CircleBuilder extends ShapeBuilder{
    ...
    @Override
    public Circle build() {
    ....
}

This is specified in section 8.4.5 of the Java Language Specification:

Return types may vary among methods that override each other if the return types are reference types. The notion of return-type-substitutability supports covariant returns, that is, the specialization of the return type to a subtype.

A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold:

  • If R1 is void then R2 is void.

  • If R1 is a primitive type, then R2 is identical to R1.

  • If R1 is a reference type then:

    • R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9), or

    • R1 = |R2|

("|R2|" refers to the erasure of the type R2, as defined in §4.6 of the JLS.)


* Prior to Java 5, Java had invariant return types, which meant the return type of a method override needed to exactly match the method being overridden.

Inimitable answered 4/2, 2013 at 20:18 Comment(0)
C
42

Yes it may differ but there are some limitations.

Before Java 5.0, when you override a method, both parameters and return type must match exactly. Java 5.0 it introduces a new facility called covariant return type. You can override a method with the same signature but return a subclass of the object returned.

In another words, a method in a subclass can return an object whose type is a subclass of the type returned by the method with the same signature in the superclass.

Crocidolite answered 11/12, 2013 at 9:2 Comment(0)
L
23

Yes, if they return a subtype. Here's an example:

package com.sandbox;

public class Sandbox {

    private static class Parent {
        public ParentReturnType run() {
            return new ParentReturnType();
        }
    }

    private static class ParentReturnType {

    }

    private static class Child extends Parent {
        @Override
        public ChildReturnType run() {
            return new ChildReturnType();
        }
    }

    private static class ChildReturnType extends ParentReturnType {
    }
}

This code compiles and runs.

Lam answered 4/2, 2013 at 20:20 Comment(0)
C
13

Broadly speaking yes return type of overriding method can be different. But it's not straight forward as there are some cases involved in this.

Case 1: If the return type is a primitive data type or void.

Output: If the return type is void or primitive then the data type of parent class method and overriding method should be the same. e.g. if the return type is int, float, string then it should be same

Case 2: If the return type is derived data type:

Output: If the return type of the parent class method is derived type then the return type of the overriding method is the same derived data type of subclass to the derived data type. e.g. Suppose I have a class A, B is a subclass to A, C is a subclass to B and D is a subclass to C; then if the super class is returning type A then the overriding method in subclass can return either A, or B/C/D type i.e. its sub types. This is also called as covariance.

Coad answered 10/6, 2016 at 3:26 Comment(2)
your this comment is ambiguous i have a class A B is subclass to A C is subclass to B D, what it means Class AB is subclass of AC or A,B are Subclass of A,C Means its confusingMccaleb
String is not a primitive type in Java.Quarterly
J
5

yes It is possible.. returns type can be different only if parent class method return type is
a super type of child class method return type..
means

class ParentClass {
    public Circle() method1() {
        return new Cirlce();
    }
}

class ChildClass extends ParentClass {
    public Square method1() {
        return new Square();
    }
}

Class Circle {

}

class Square extends Circle {

}


If this is the then different return type can be allowed...
Jovi answered 1/3, 2016 at 17:44 Comment(0)
N
4

The other answers are all correct, but surprisingly all leaving out the theoretical aspect here: return types can be different, but they can only restrict the type used in the super class because of the Liskov Substitution Principle.

It is super simple: when you have "client" code that calls some method:

int foo = someBar.bar();

then the above has to work (and return something that is an int no matter which implementation of bar() is invoked).

Meaning: if there is a Bar subclass that overrides bar() then you still have to return something that doesn't break "caller code".

In other words: assume that the base bar() is supposed to return int. Then a subclass could return short - but not long because callers will be fine dealing with a short value, but not a long!

Ninnetta answered 16/3, 2018 at 13:25 Comment(0)
R
3

well, the answer is yes... AND NO.

depends on the question. everybody here answered regarding Java >= 5, and some mentioned that Java < 5 does not feature covariant return types.

actually, the Java language spec >= 5 supports it, but the Java runtime does not. in particular, the JVM was not updated to support covariant return types.

in what was seen then as a "clever" move but ended up being one of the worst design decisions in Java's history, Java 5 implemented a bunch of new language features without modifying the JVM or the classfile spec at all. instead all features were implemented with trickery in javac: the compiler generates/uses plain classes for nested/inner classes, type erasure and casts for generics, synthetic accessors for nested/inner class private "friendship", synthetic instance fields for outer 'this' pointers, synthetic static fields for '.class' literals, etc, etc.

and covariant return types is yet more syntactic sugar added by javac.

for example, when compiling this:

class Base {
  Object get() { return null; }
}

class Derived extends Base {
  @Override
  @SomeAnnotation
  Integer get() { return null; }
}

javac will output two get methods in the Derived class:

Integer Integer:Derived:get() { return null; }
synthetic bridge Object Object:Derived:get() { return Integer:Derived:get(); }

the generated bridge method (marked synthetic and bridge in bytecode) is what actually overrides Object:Base:get() because, to the JVM, methods with different return types are completely independent and cannot override each other. to provide the expected behavior, the bridge simply calls your "real" method. in the example above, javac will annotate both bridge and real methods in Derived with @SomeAnnotation.

note that you cannot hand-code this solution in Java < 5, because bridge and real methods only differ in return type and thus they cannot coexist in a Java program. but in the JVM world, method return types are part of the method signature (just like their arguments) and so the two methods named the same and taking the same arguments are nonetheless seen as completely independent by the JVM due to their differing return types, and can coexist.

(BTW, the types of fields are similarly part of the field signature in bytecode, so it is legal to have several fields of different types but named the same within a single bytecode class.)

so to answer your question fully: the JVM does not support covariant return types, but javac >= 5 fakes it at compile time with a coating of sweet syntactic sugar.

Rags answered 2/4, 2019 at 8:52 Comment(0)
L
1

The return type must be the same as, or a subtype of, the return type declared in the original overridden method in the superclass.

Lindo answered 4/2, 2013 at 20:36 Comment(1)
You should combine your two answers.Opinion
L
1

Overriding and Return Types, and Covariant Returns
the subclass must define a method that matches the inherited version exactly. Or, as of Java 5, you're allowed to change the return type in the

sample code


                                                                                                            class Alpha {
          Alpha doStuff(char c) {
                  return new Alpha();
              }
           }
             class Beta extends Alpha {
                    Beta doStuff(char c) { // legal override in Java 1.5
                    return new Beta();
                    }
             } } 
As of Java 5, this code will compile. If you were to attempt to compile this code with a 1.4 compiler will say attempting to use incompatible return type – sandeep1987 1 min ago
Lindo answered 4/2, 2013 at 21:0 Comment(0)
A
1
class Phone {
    public Phone getMsg() {
        System.out.println("phone...");
        return new Phone();
    }
}

class Samsung extends Phone{
    @Override
    public Samsung getMsg() {
        System.out.println("samsung...");
        return new Samsung();
    }
    
    public static void main(String[] args) {
        Phone p=new Samsung();
        p.getMsg();
    }
}
Anjaanjali answered 12/7, 2020 at 7:24 Comment(2)
How does this answer the question?Johen
this is the example of different return type.Anjaanjali
Z
0

YES it can be possible

class base {

 base show(){

System.out.println("base class");

return new base();

}
}

class sub extends base{

sub show(){

    System.out.println("sub class");

    return new sub();

 }
}

class inheritance{

 public static void main(String []args) {

        sub obj=new sub();

            obj.show();
 }
}
Zima answered 23/7, 2014 at 20:9 Comment(0)
A
0

Yes. It is possible for overridden methods to have different return type .

But the limitations are that the overridden method must have a return type that is more specific type of the return type of the actual method.

All the answers have given examples of the overridden method to have a return type which is a subclass of the return type of the actual method.

For example :

public class Foo{

   //method which returns Foo
  Foo getFoo(){
      //your code         
  }

}

 public class subFoo extends Foo{

  //Overridden method which returns subclass of Foo
  @Override
  subFoo getFoo(){
      //your code         
  }

}

But this is not only limited to subclass.Even classes that implement an interface are a specific type of the interface and thus can be a return type where the interface is expected.

For example :

public interface Foo{

   //method which returns Foo
  Foo getFoo();

}

 public class Fizz implements Foo{

  //Overridden method which returns Fizz(as it implements Foo)
  @Override
  Fizz getFoo(){
      //your code         
  }

}
Assr answered 5/1, 2019 at 13:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.