n3x7
n3x7

Reputation: 83

Interface inheritance - changing method parameters

I have difficulties understanding the java way of interpreting interface inheritance, example:

public interface Model {
    Model getModel();
    void setModel(Model model);
}

public class BaseModel implements Model {
    @Override
    public BaseModel getModel() { return  null; } // works

    @Override
    public void setModel(BaseModel model) {} // compilation error, it wants Model instead of BaseModel
}

Could anyone explain why the first method works, and the second doesn't?

Upvotes: 8

Views: 1255

Answers (4)

shikjohari
shikjohari

Reputation: 2288

Method name and parameter types makes a method signature in Java and not the return type. When you override a method the signature of the method should be the same If you change the signature it ll be overloading and not overriding - to see it if you remove the @Override annotation it ll work.

Upvotes: 2

Mureinik
Mureinik

Reputation: 311163

In order to understand this, you should ask yourself "can I substitude BaseModel for any usage of the Model interface"?

When you specialize the return value, this works fine. Even if getModel() returns a BaseModel, it can always be assigned to a Model variable.

Model model = myModel.getModel();

The other way round is not true, however:

SomeOtherModel other = ...;
myModel.setModel(other); // no problem
myBaseModel.setModel(other); // other is not a BaseModel!

if setModel were to accept a BaseModel parameter you'd break its ability to be set with other implementations of Model. Hence, this is not allowed.

Upvotes: 5

SMA
SMA

Reputation: 37023

Your first method's return type is covariant and is allowed and return type is not a part of method signature hence its allowed

While parameter to a method is a part of signature and has to strictly follow the interface signature and hence it fails in your case.

Now since you annotated your method with @Override, you are trying to override the method hence compiler complains about the same. If you just remove that and implement method as per interface in addition to existing implementation then you will overload the method.

Upvotes: 5

Bathsheba
Bathsheba

Reputation: 234665

It's how function overriding works.

  1. The function parameters have to be exactly identical.

  2. The return types can be different but must be related.

So in your case, getModel is fine since the return type (BaseModel) is related to Model, but setModel is not valid since the parameter types are dissimilar.

Upvotes: 3

Related Questions