Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Interface: Inheriting, Overriding, and Overloading Methods

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

like image 746
akjain Avatar asked May 18 '09 12:05

akjain


4 Answers

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.

like image 114
David Schmitt Avatar answered Oct 12 '22 19:10

David Schmitt


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;
    // }
}
like image 32
Daniel Schneller Avatar answered Oct 12 '22 21:10

Daniel Schneller


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()
   {
      ...
   }
}
like image 26
Mnementh Avatar answered Oct 12 '22 20:10

Mnementh


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).

like image 1
Tom Hawtin - tackline Avatar answered Oct 12 '22 19:10

Tom Hawtin - tackline