Hello,
I have the following two interfaces.
//-----------------------
public class B extends A
//-----------------------
public interface IA {
public A getFormat();
public interface IB extends IA {
public B getFormat();
}
}
//-----------------------
Here, interface IB overrides the getFormat() method of its
super-interface IA. Instead of returning an A it now returns a B. Note
that B extends A.
In my eclipse, if I choose a compiler compliance level <= Java 1.4 this
gives an error "The return type is incompatible with IA.getFormat()". If
I choose a compliance level >= 5.0 it is OK without problem.
Is the overriding mechanism really different between Java 1.4 and 5?
(couldn't find any info about this on the new features page of J2SE 5.0)
What can I do to still use this construct on a Java 1.3 compatible JVM?
Thanks
Phil
Mark Space - 08 Jan 2008 15:57 GMT
> In my eclipse, if I choose a compiler compliance level <= Java 1.4 this
> gives an error "The return type is incompatible with IA.getFormat()". If
> I choose a compliance level >= 5.0 it is OK without problem.
I think I remember hearing something about this. It's not inheritance,
per se, but the allowed return types when overriding a method. 1.5 is
allowed to be looser (type or subtype) than 1.4 (same type only). Sorry
I don't have a JLS reference for you.
1.3 is unaffected by this change....
Roedy Green - 08 Jan 2008 16:30 GMT
>What can I do to still use this construct on a Java 1.3 compatible JVM?
You can't. There methods must differ in more than just return type.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Andreas Leitgeb - 08 Jan 2008 17:04 GMT
> public interface IA {
> public A getFormat();
[quoted text clipped - 3 lines]
> }
> What can I do to still use this construct on a Java 1.3 compatible JVM?
Change interface IB's method to also return A.
Sorry, no other way. (any class that implements IB will
of course still return B objects at runtime, but they
can't state this fact such that old JVM knows.)
Lew - 09 Jan 2008 02:54 GMT
>> public interface IA {
>> public A getFormat();
[quoted text clipped - 8 lines]
> of course still return B objects at runtime, but they
> can't state this fact such that old JVM knows.)
This is called "covariant return", and was introduced in 1.5. An overriding
method may return a subtype ("covariant type") of the parent method's return
type. You cannot have two different overrides that differ only in return
type, though.
In 1.4 and earlier (you do realize that 1.3 has been retired for some time
now, don't you? And that 1.4 hits its "End-of-Life" this very year?)
covariant return types are not permitted.
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8>
Specifically ss. 8.4.8.3.
> If a method declaration d1 with return type R1 overrides or hides the declaration
> of another method d2 with return type R2, then d1 must be return-type substitutable
> for d2, or a compile-time error occurs. Furthermore, if R1 is not a subtype of R2,
> an unchecked warning must be issued (unless suppressed (§9.6.1.5)).

Signature
Lew
Philipp - 09 Jan 2008 08:56 GMT
>>> public interface IA {
>>> public A getFormat();
[quoted text clipped - 10 lines]
>
> This is called "covariant return", and was introduced in 1.5.
OK. I didn't know the correct term. This use of the word "covariant"
somewhat differs from the mathematical sense...
> <http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8>
> Specifically ss. 8.4.8.3.
Thanks for the ref.
Phil
Lew - 09 Jan 2008 14:09 GMT
>>>> public interface IA {
>>>> public A getFormat();
[quoted text clipped - 13 lines]
> OK. I didn't know the correct term. This use of the word "covariant"
> somewhat differs from the mathematical sense...
I sat on a bus talking to another programmer once. After ten minutes, another
lady broke in and said, "I know every single word you guys have been using,
but I have no idea what you've been talking about."
Programming uses terms that differ from their English sense. Let alone their
mathematical.
For another programming term whose meaning differs from the mathematical,
check out "idempotent".

Signature
Lew
Roedy Green - 09 Jan 2008 10:29 GMT
>Is the overriding mechanism really different between Java 1.4 and 5?
>(couldn't find any info about this on the new features page of J2SE 5.0)
see http://mindprod.com/jgloss/covariance.html

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Neo_it - 09 Jan 2008 10:30 GMT
> Hello,
> I have the following two interfaces.
[quoted text clipped - 27 lines]
> Thanks
> Phil
This feature is introduce in J2SE 5.0, in which you can override the
method with the covariant return type. this covariant term is used in
J2SE 5.0 document. if i say in broad term then you can use any class
that is in class hierarchy.means any sup class or class specified in
return type. internally it do implicit type conversion for you.
Lew - 09 Jan 2008 14:39 GMT
> This feature is introduce in J2SE 5.0, in which you can override the
> method with the covariant return type. this covariant term is used in
> J2SE 5.0 document. if i say in broad term then you can use any class
> that is in class hierarchy.means any sup class or class specified in
> return type. internally it do implicit type conversion for you.
Here's why it's allowed. Consider
public interface StatementCreator
{
java.sql.Statement createStatement() throws java.sql.SQLException;
}
and an implementing class with
public com.lewscanon.sql.Statement createStatement()
throws java.sql.SQLException
where the return type implements java.sql.Statement. From the point of view
of any interface-typed variable that invokes the method, it is getting a
java.sql.Statement back, so the contract is fulfilled. It's a natural
concomitant of implicit widening conversions. As long as what you want is
wider than what you got, you're fine.
The put side is the converse. What you want to put has to be narrower, so the
method signature of the callee has to be wider. This is "contravariant", or
supertype substitution, contrasted with the "covariant" or subtype
substitution in the return part of the method signature. This is where the
concept of method overloads and the rules for finding the narrowest available
signature, i.e., contravariant type pattern apply.
The terms "contravariant" and "covariant" are more common in the context of
generics, where the wildcard "? extends" is a covariant type, and "? super" is
the contravariant. You see the latter a lot in Comparables and the like:
public static <T extends Comparable<? super T>> void sort(List<T> list)
<http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List)>
public static <T> void sort(List<T> list, Comparator<? super T> c)
<http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.
List,%20java.util.Comparator)>

Signature
Lew