Rahul
Rahul

Reputation: 45060

How does a class consider its super class's method as it's interface method's implementation?

Instead of talking theory, let me directly jump to the example to demonstrate what I'm trying to ask.

// The below piece of code is present in a single java file named "MyMain.java"
public class MyMain {
    public static void main(String args[]) {
        IFace iFace = new CSub();
        iFace.method(); // This method essentially belongs to CSuper which doesn't implement IFace
    }
}

interface IFace {
    void method(); // Method in the interface
}

class CSuper {
    public void method(){ // some method in this class, but not the one which implements the method of IFace
        System.out.println("I'm not implementing IFace's method");
    }
}

class CSub extends CSuper implements IFace {} // No method implemented in the class and yet no error.

Obviously the above piece of code works as I was able to get the output I'm not implementing IFace's method upon execution.

My question is, how does CSub take the method() of CSUper as the implementation of the method() of IFace interface. It seems like inheritance is the one behind this, but I need some concrete answer for that. And also, is there a JLS reference for this which can clarify how this is possible via inheritance?


And a follow up question for that is, say there is some reason why this works(As I'm guessing that it is inheritance but need to be sure about it), why doesn't the same code snippet work if I do either of the below changes?

Change 1:

class CSuper {
    void method(){ // there is no access specifier, thus default(package)
        System.out.println("I'm not implementing IFace's method");
    }
}

Change 2:

class CSuper {
    protected void method(){ // access specifier is now protected
        System.out.println("I'm not implementing IFace's method");
    }
}

For both the above changes I do, I get an compilation error saying The inherited method CSUper.method() canoot hide the public abstract method in IFace on this line

class CSub extends CSuper implements IFace {}

Why is it so? Since it is inheritance, both protected and default access specifier should work, as all the classes are present in the very same file. And method() must have been inherited to the CSub class, just like how it did in the part one of the question. Can anybody highlight on this case too?

Upvotes: 0

Views: 106

Answers (2)

Tim B
Tim B

Reputation: 41178

The answer to part 1 is quite simple - the Interface simply requires that the class the Interface is part of implement a method with that signature.

It doesn't care where the method is actually defined - so long as it exists then the Interface is valid.

The reason for that is fairly obvious as well. All the Interface is saying is "any object with this interface, you can call a function called X with parameters Y and it will return Z". By inheriting that method from a super class you are meeting that requirement.

This also answers part 2. To implement an Interface the implementing method must be Public - so anyone can access it.

By making the super class method package private or protected it is no longer meeting the requirement.

class CSub extends CSuper implements IFace {
     public method() {
         super.method();
     }
}

By doing that you can make the method public (making access more broad through inheritance is allowed, you just can't make things more restricted) and it will now satisfy the interface again.

The access restrictions are part of the method signature. To explain why think about a class being handed an IFace x. They will then try to call x.method() which is defined in the Interface.

If they are not in the same package as your implementation they still need to be able to call x.method(). Because of this x.method() must be public in order to satisfy the interface - since otherwise people can get an IFace but the method will not be available to them.

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1500225

Tim's answered most of this. For the JLS reference, from section 8.1.5:

Unless the class being declared is abstract, the declarations of all the method members of each direct superinterface must be implemented either by a declaration in this class or by an existing method declaration inherited from the direct superclass, because a class that is not abstract is not permitted to have abstract methods (§8.1.1.1).

Upvotes: 4

Related Questions