Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding Object class methods within an interface in Java

Tags:

java

Let's consider the following simple code in Java.

package temppkg;

interface Interface
{
    @Override
    public abstract boolean equals(java.lang.Object arg);

    @Override
    public abstract String toString();

    public void show();
}

final class Demo implements Interface
{
    public void show()
    {
        System.out.println("Method invoked.");
    }
}

final public class Main
{
    public static void main(String...args)
    {
        new Demo().show();
    }
}

In the above code snippet, the interface named Interface has some Object class methods from JDK and they are with the @Override annotation even though they are abstract. Now, the class Demo has implemented Interface and has not implemented the equals() and the toString(); methods. Still the compiler doesn't complain and the program is running successfully. Why? What is the relation between interfaces and the object class in Java?

like image 635
Lion Avatar asked Jan 04 '12 04:01

Lion


3 Answers

The Java Language Specification clearly says that the members of an interface are those which are declared in the interface and those which are inherited from direct super interfaces. If an interface has no direct superinterface then the interface implicitly declares a public abstract member method corresponding to each public instance method declared in the Object class, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by that interface. This is what makes the signatures of the Object methods available to the compiler and the code compiles without any error. Remember if the interface tries to declare a public instance method declared 'final' in the Object class then it'll result into a compile-time error. For example, 'public final Class getClass()' is a public instance method declared 'final' in the Object class and therefore if an interface tries to declare a method with this signature then the compilation will fail.

http://geekexplains.blogspot.com/2008/06/do-interfaces-really-inherit-from-class.html

like image 82
Jyotirup Avatar answered Nov 14 '22 21:11

Jyotirup


Check out JLS 9.2:

If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.

In other words, every interface implicitly defines each of Object's methods, and you can therefore @Override those methods. The other methods aren't defined in Object, so you can't override them.

like image 24
yshavit Avatar answered Nov 14 '22 21:11

yshavit


In Interface you're not actually overriding anything - an interface by definition can not provide implementations for any of its methods. The class Demo just inherits the equals and toString implementation from Object.

In essence an interface in Java contains a set of zero or more method signatures (all of them are implicitly abstract, in your code you made it explicit by adding the keyword abstract), and the concrete classes that implement the interface must provide an implementation for those methods. In the case of your code, that implementation comes from Object, since all the classes implicitly extend Object, which provides default implementations for equals and toString (among other methods).

You really shouldn't mark the methods in an interface with @Override, as you have seen, it's confusing and serves for no practical purpose. Instead, use @Override in the methods in the concrete class that implement the methods of the interface, like this:

class Demo implements Interface {
    @Override
    public void show() {
        System.out.println("Method invoked.");
    }
}

Also, it's completely unnecessary to declare equals and toString in an interface, so you're better off with this definition:

interface Interface {
    public void show();
}
like image 44
Óscar López Avatar answered Nov 14 '22 21:11

Óscar López