0

When overriding method i return type a subtype of the super method return type. But why i can't do the same thing with the method parameter list.

Ex.

public class OverrideTest implements CustomersI {
    @Override
    public ArrayList<Customer> getCustomers(ArrayList<String> names) {
         // TODO Auto-generated method stub
         return null;
    }
}

interface CustomersI{
    List<Customer> getCustomers(List<String> names);
}

class Customer{
    Customer(String name){
    }
}
  • why i can change return type ArrayList instead of List and can't do the same with param list.
pobrelkey
  • 5,853
  • 20
  • 29
Khaled Lela
  • 7,831
  • 6
  • 45
  • 73
  • I don't really understand why you'd need/want to. [Coding to interfaces](http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) is much nicer. – Dan Temple Mar 11 '14 at 08:13
  • List and ArrayList are different types and one overloads, not overrides the other. – Peter Lawrey Mar 11 '14 at 08:13

4 Answers4

2

Because you wouldn't respect the contract of the interface. The interface method says: anyone can call me with any kind of List<String>. The class implements this interface, bu says: Anyone can call me, but not with any kind of List<String>: only ArrayList<String>. This is thus invalid, because the method doesn't fulfilled the contract declared in the interface.

Returning a more specific type doesn't have this problem. The interface method says: if you call me, you'll get a List<Customer> as a result. And the class method says: if you call me, you'll have a List as a result, and I can even be more precise: you'll get an ArrayList<Customer> as a result, which is a List<Customer>.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • but why we can change the return type of overriden method from list to arraylist ?? – Kick Mar 11 '14 at 08:15
  • thnks for explanation but one more question you mean to say we can change the return type to its subclasses. – Kick Mar 11 '14 at 08:21
  • Thanks for your explanation, and i think @Rohitha show your point of view by his code line `CustomersI customers = new OverrideTest();` – Khaled Lela Mar 11 '14 at 08:47
1

we can declare variable using super type and initialize to sub type.

CustomersI customers = new OverrideTest();

But in runtime, actual object OverrideTest() is acting.

When you you pass params to customers.getCustomers(..) according to your interface, it allows any sub type of List. but actual object (OverrideTest) only allowed ArrayList or its sub type. for ex. suppose you are going to pass object of LinkedList<Customer>. Now your getCustomers in OverrideTest class is not allowed to pass this object. Therefore your implementation is wrong.

So, You cannot use sub-types as parameters but you can use supper types.

Rohitha
  • 116
  • 1
  • 8
  • +1 for your answer,Good explanation. But what about return type. – Khaled Lela Mar 11 '14 at 08:40
  • consider we declare `CustomersI customers = new OverrideTest();`. as same as you can assign any subtype to a variable. ex. `List results = customers.getCustomers(..); ` now real get customer method return `ArrayList` which is sub type of `List`. The variable `result` is accepted any List. therefore your return type is valid – Rohitha Mar 11 '14 at 08:59
0

Because the function signature is different if parameter list is changed. For overriding the function signature has to remain same because when calling a function the function signature is matched. The same idea allows overloading of functions where the called function is decided by the parameters compared with function signature.

Hope this helps

0
  1. You can't change param list is because of the definition of method overriding.

    The implementation in the subclass overrides (replaces) the implementation in the superclass by providing a method that has same name, same parameters or signature, and same return type as the method in the parent class.

  2. You can change return type is because Java introduced Covariant return type in Java 5.

    a covariant return type of a method is one that can be replaced by a "narrower" type when the method is overridden in a subclass.

Here is an example of using covariant return type when overriding Object.clone().

// class Object
protected native Object clone() throws CloneNotSupportedException;

// class Customer
@Override
protected Customer clone() throws CloneNotSupportedException {
    ...
}

Prior to Java 5 your overridden clone() method in Customer would also have to return Object and therefore a cast would be required.

Royce Lee
  • 581
  • 4
  • 2