tags:

views:

159

answers:

4

Following interface and classes are successfully compiled. Problem is mentioned in the output below :

interface MyInterface{}

class MyClass implements MyInterface{}

class InterDoubt{

    static MyInterface mi ;//= new MyClass() ;

    public static void main(String[] args){
        System.out.println("X") ;

        try{
            synchronized(mi){
                try{
                    mi.wait(4000) ;
                }
                catch(InterruptedException ie){
                    System.out.println("Exception occured at main.") ;
                }
            }
        }
        catch(Exception e){
            System.out.println("voilla, MyInterface is an interface,\n" + 
                       "then why compiler allows compilation of\n" +
                       "mi.getClass(), mi.wait().\n" +
                       "Or how the methods of Object class are available in an interface."
            );
        }

        System.out.println("Y") ;
    }
}

output :

X

voilla, MyInterface is an interface,

then why compiler allows compilation of

mi.getClass(), mi.wait().

Or how the methods of Object class are available in an interface.

Y


Edited :- I am accepting answer from disown, as it's the most explanatory. But after reading the answer, one more issue get's populated :-

"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" (Quoted from explanation).

then why the following code is getting successfully compiled :-

interface MyInter{
    public void method() ;
}

class MyClass implements MyInter{

    public final void method() {
        .......
        .......
              .......
    }

}
+2  A: 

At run time there should be a real object (or null) behind the reference mi. The real type will implement this interface hence the compiler allows it. At run time any type that implements that interface could be there.

Preet Sangha
Given an interface type, an concrete type implementing that interface, and a interface reference to an instance of the concrete type, it is not true that the compiler will allow you to call methods on the concrete instance not specified in the interface. Furthermore, the Object methods are not part of any (explicit) interface at all.
disown
A: 

Yes, all Object's methods are available to everything but Primitive value. Interface objects are still objects so they have Object's methods.

NawaMan
Interface instances are _not_ objects, they only delegate the public methods of objects.
disown
Interface instances must be objects. All things DATA except primitive value are object. When you create an instance, you need to create from a class (eventhough, you hold it with an interface variable). To create a class that implement an object, the class must inherit something (if you do not specified it, the class will inherit Object). This means that every instances (including those held by an variable of Interfaces) are ALWAYS Object.
NawaMan
TYPO: "To create a class that implement an object," => "To create a class that implement an Interface,". :-p
NawaMan
Read the article which I refer to in my first post. It is not true that interfaces are objects. It is more entangled with the language than so (consider invokevirtual et al).
disown
+3  A: 

What you are correctly pointing out as an exception is specified in the Java Language Specification. Interfaces will automatically get all members from the class java.lang.Object added. From here:

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.

disown
A: 

The cast (Object)mi will always succeed so why should you be required to provide it?

Joshua