Eric Lefevre-Ardant on Java & Agile

March 16, 2007

Change signature of interface methods in implementations

Filed under: java — Eric Lefevre-Ardant @ 5:55 pm

Every once in a while, I learn a new fact that reminds me to stay humble with my knowledge of Java.

As you know, to implement a method defined in an interface, you are supposed to provide a method with the same signature.
Let’s take:

public interface Test {
	Collection getSomething();
}

If you implement it in this way:

public class TestImpl implements Test {
	public Object getSomething() {
		return null;
	}
}

You’ll get a compiler error, as the return type is not compatible. So the right way it to write:

public class TestImpl implements Test {
	public Collection getSomething() {
		return null;
	}
}

Nothing special here.

Now, what about the other way round? Something like this?

public interface Test {
	Object getSomething();
}
public class TestImpl implements Test {
	public Collection getSomething() {
		return null;
	}
}

Incredibly, this works perfectly, both at compiler and runtime.

Of course, once you think about it, it makes perfect sense. The signature remains compatible, since your new method is still returning an Object, albeit a specific one.

Still, it is surprising. Well, to me at least. It is something that we are not *told*! ;-)

3 Comments »

  1. Interesting, but does it work only for the return type? i guess so!
    anyway i tried it in dotnet and it doesnt work…

    Comment by Sadek Drobi — March 19, 2007 @ 1:43 pm

  2. Well, clearly, it would not be able to give a more specialize type for the parameters in an implementation, as you could get an invalid parameter type. So you cannot declare
    void setSomething(Object obj);
    in an interface and implement it with
    void setSomething(String str) {…}
    as you would be running the risk of getting something not compatible with String.

    However, the opposite would be interesting. Say you declare
    void setSomething(String str);
    if you implement it with
    void setSomething(Object obj) {…}
    well, it *could* work! Except that it doesn’t, of course. The compiler flags it.

    Regarding .NET, I’m a bit surprised that you cannot generalize the return type. It could mean that .NET is treating the method signature a bit differently than Java does. If I recall, the definition of a method signature in Java only contains the name and the parameters, but not the return type (or the throws declaration).

    Comment by Eric Lefevre — March 19, 2007 @ 2:26 pm

  3. I don’t think that this worked before JDK5

    Comment by David Gageot — April 24, 2007 @ 2:16 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress