views:

1821

answers:

4

Hi All,

In "THE Java™ Programming Language, Fourth Edition" By Ken Arnold, James Gosling, David Holmes, its mentioned that:

paragraph: (4.3.2) "Similarly, if an interface inherits more than one method with the same signature, or if a class implements different interfaces containing a method with the same signature, there is only one such method. The implementation of this method is ultimately defined by the class implementing the interfaces, and there is no ambiguity there. If the methods have the same signature but different return types, then one of the return types must be a subtype of all the others, otherwise a compile-time error occurs. The implementation must define a method that returns that common subtype."

Can anybody give me some example code that justifies the points of above paragraph ?

I tried to write the code and test what is mentioned but I am getting compile-time error the sub-interface hides the base interface method so can only implement sub-interface method.

Thanks in advance. -Arun

A: 
interface A
{
   void foo();
   //int bar(); <-- conflicts with B.bar() because of different return type
}

interface B
{
   void foo();
   //double bar(); <-- conflicts with A.bar() because of different return type
}

class C implements A, B
{
   void foo() // this implements A.foo() AND B.foo()
   {
      ...
   }
}
Mnementh
+5  A: 
interface A {
    void method();
    Object returnMethod();
}
interface B {
    void method();
    B returnMethod();
}

class Impl implements A,B 
{
    void method() { }
    B returnMethod() { }
}

As you can see, Impl.method() implements both A.method() and B.method(), while Impl.returnMethod() returns a B, which is a child of Object, thus fulfilling A.returnMethod()'s contract too. Would the latter require a return type that is not a parent of B.returnMethod()'s return type that would be a comile error, since no such implementation could exist in Impl.

David Schmitt
But Impl has to implement object ReturnMethod(), right?
Norbert Hartl
Is that C#? The question is about Java.
Joachim Sauer
I don't think it matters which language ;)
Norbert Hartl
easy to fix that :)
Michael Borgwardt
And no, Impl must implement the more specific return type in order to satisfy both interfaces.
Michael Borgwardt
That was indeed funnny :)
Norbert Hartl
Oh, right I was on the wrong track
Norbert Hartl
A: 

Is this what you mean?:

interface A {
    Object get();
}
interface B {
    Number get();
}

abstract class MyClass implements A, B {
    // Try to override A.get, but cause a compile error.
    public Object get() { return null; }
}

Such a method in MyClass is automatically generated by javac as a synthetic bridge method. You must implement a single method returning a type compatible with all of the implemented/overridden methods (in this case Number/Integer/Double/etc).

Tom Hawtin - tackline
+1  A: 

In the following two interfaces methodA() is identically defined in terms of parameters (none) and return type (int). The implementation class at the bottom defines a single method with this exact signature. As it complies to both interfaces, you get no problem there - any calls made via a reference of type InterfaceA or InterfaceB will be dispatched to this implementation.

The second methodB() is defined as returning any subtype of Number (or Number itself) in InterfaceA. InterfaceB defines methodB() as returning an Integer which is a subtype of Number. The implementation class actually implements the method with Integer, thus complying to the contract of both InterfaceA and InterfaceB. No problem here either. The commented out case of methodB() being implemented as returning a Double however would not work: While it would satisfy the contract of InterfaceA, it would conflict with InterfaceB (which demands an Integer).

If InterfaceA and InterfaceB were also specifying (different) contracts for a methodC() (commented out in the example) this would be contradictory and create a compiler error. Implementing both signatures (differing only in return type) is not allowed in Java.

The above rules would also hold true if were to add any parameters to the methods. For simplicity I kept this out of the example.

public interface InterfaceA {
    public int methodA();
    public Number methodB();
    // public int methodC(); // conflicting return type
}

public interface InterfaceB {
    public int methodA();
    public Integer methodB();
    // public String methodC(); // conflicting return type
}

public class ImplementationOfAandB implements InterfaceA, InterfaceB {
    public int methodA() {
        return 0;
    }
    public Integer methodB() {
        return null;
    }
    // This would NOT work:
    // public Double methodB() {
    //     return null;
    // }
}
Daniel Schneller
Everyone I am really sorry - I was trying to test what was mentioned in the above mentioned para using j2sdk1.4.2_08 - I didn't realize that the book is written for JDK1.5So that means if you compile the code snippet by "Daniel Schneller" using JDK1.4 you will get a "ImplementationOfAandB.java:17: methodB() in ImplementationOfAandB cannot implement methodB() in InterfaceA; attempting to use incompatible return type" compilation error whereas with JDK1.5 it just runs fine.
akjain