JDK-6748088 : Abstract classes and interfaces should inherit override-equivalent methods similarly
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2008-09-12
  • Updated: 2014-02-26
  • Resolved: 2011-07-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 rcFixed
Related Reports
Relates :  
Relates :  
Description
Davide Ancona writes:

9.4.1 Inheritance and Overriding: "It is possible for an interface to inherit several methods with override-equivalent signatures (��8.4.2). Such a situation does not in itself cause a compile-time error. The interface is considered to inherit all the methods. However, *A* one of the inherited methods must must be return type substitutable for any other inherited method; otherwise, a compile-time error occurs (The throws clauses do not cause errors in this case.)"

8.4.8.4 Inheriting Methods with Override-Equivalent Signatures: "If all the inherited methods are abstract, then the class is necessarily an abstract class and is considered to inherit all the abstract methods. A compile-time error occurs *B* if, for any two such inherited methods, one of the methods is not return type substitutable for the other (The throws clauses do not cause errors in this case.)"

What seems quite bizarre to us is that the condition *B* for type-safe inheritance of methods with override-equivalent signatures for abstract classes is strictly stronger than condition *A* for interfaces.

We have tried to compile the following program:

interface T1 extends T2,T3{}
interface T2{}
interface T3{}

interface I1{ T1 m(); }
interface I2{ T2 m(); }
interface I3{ T3 m(); }

interface I extends I1,I2,I3{}

Despite in this case condition *A* is verified, the compiler (1.6.0_06) detects the following error:
  exceptions.java:17: types I3 and I2 are incompatible; both define m(), but with unrelated return types
  interface I extends I1,I2,I3{}

Comments
EVALUATION It is intended that Java never allows overloading based on return type. If a type's members would include multiple methods with override-equivalent signatures, one must be chosen. The one with the deepest return type is ideal. This applies whether choice occurs within an interface or an abstract class. As you say, *B* is very strong, and unnecessarily so. The fact that T2 and T3 are incomparable is irrelevant to the interface (I) or abstract class (analogous to I) which inherits m() because it only needs to choose one m(), and the one returning T3 is fine. Therefore, JLS 8.4.8.4 should be relaxed, and use the same wording as 9.4.1: "One of the inherited methods must must be return type substitutable for any other inherited method; otherwise, a compile-time error occurs." For the sample code involving interfaces, the compiler is in error, as reported in other CRs.
12-09-2008