Reputation: 83
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
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
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
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
Reputation: 234665
It's how function overriding works.
The function parameters have to be exactly identical.
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