Reputation: 25612
This code is invalid:
interface Foo
{
public void foo(final String string);
}
public class Bar implements Foo
{
// Error: does not override.
@Override public void foo(final Object object)
{
}
}
Because every String
is obviously an Object
, I would expect this code to be perfectly fine: any code that depends on giving foo()
a String
would stil function when foo()
actually takes an Object
.
It appears, though, that method signatures have to be identical to those of the methods they're overriding. Why?
Upvotes: 2
Views: 93
Reputation: 31
It's just the constructs of the Java programming language. The structure of Java programs will grow on you. So for now just try and adjust.
Upvotes: 0
Reputation: 78639
I think this is a classical contravariance issue. Your interface requires a string to be passed as parameter, you want an implementation that accepts an object (because, after all, strings are also objects).
The problem is that if you allowed that, then you could no longer guarantee that the parameter being required by the interface is a string or any one of its ancestors. You might just as well pass any object to your implementation and you would be breaking the contract of the interface, putting in danger the type safety and type coherence of your design.
You do have options, though:
public class Bar implements Foo
{
@Override public void foo(final String object)
{
}
public void foo(final Object object)
{
foo((String) object);
}
}
By this, you would be ensuring that object is actually a string, making possible to the type system to check that you are actually complying with the interface contract established in the method signature.
Is there a particular scenario in which you would consider your contravariance example to be requirement?
Upvotes: 0
Reputation: 1676
'loosening' as you put it should not impact on someone expecting to use your interface defined method in a particular way, as any methods you call on that object should in theory be callable on the specified object, but Eugene's point stands, becaause there would probably be a little compiler headache to deal with in determining what method you actually intended to override if you just vaguely want to stick to the interfaces specification. Also, why whould this be desireable if you are going to stick to moving up the inheritance heirarchy, because surelely you will be able to do all you want to the thing further down the hierarchy as to 'Object' for example? Possibly casting inside your method would solve your problem? If it is possible to do what you want to do, you will also probably start treading on the polymorphism paradigm.
Upvotes: 0
Reputation: 13139
What if
interface Foo
{
void foo(String string);
void foo(Object string);
}
Then which method is overridden by Bar?
Upvotes: 4