6

Can anybody explain the working of following code...?

interface myInterface{}

public class Main {

    public static void main(String[] args) {

        System.out.println(new myInterface(){public String toString(){return "myInterfacetoString";}});

        System.out.println(new myInterface(){public String myFunction(){return "myInterfacemyFunction";}});
    }
}

Output is...

myInterfacetoString
primitivedemo.Main$2@9304b1

All answers saying that myInterface in println() statement is anonymous class. But as I already declared it as an interface, why does it allow me to create anonymous class of same name....?

again...if these are anonymous classes then class main should allow me to give any name to these anonymous classes..But if try to do so..I'm getting compilation error

vodkhang
  • 18,639
  • 11
  • 76
  • 110
Siddhi
  • 63
  • 6
  • Is this homework, or curiosity? It's considered good form to tag homework questions as such. – ojrac Jun 05 '10 at 02:17
  • 1
    Siddhi, great question. However, I suggest that you dont change the question too often with significantly new content. Instead, you can submit a new question and reference this one in it. – akf Jun 05 '10 at 02:53
  • This is making an instance of an anonymous class implementing an empty interface. One overrides toString() so System.out.println will automatically use that. The other has myFunction, which doesn't get called, so it uses Object's toString() which gives a bit of information including the address of the object. – mk12 Jun 05 '10 at 03:12
  • Thanks all.... but I'm still confused... bcoz I'm not getting why it is treated as anonymous class? For me it seems like instantiating interface or abstract class... which contradicts to my understanding of abstract class & interface. – Siddhi Jun 05 '10 at 03:26
  • I already editted my answer to have a new, clearer explanation for anonymous class for interface. You should also look at the link, it is really good:) – vodkhang Jun 05 '10 at 04:11
  • @Siddhi, You are creating an anonymous class which extends/implements and abstract class. It is not an instance of that class or interface as the syntax appears to be. – Peter Lawrey Jun 05 '10 at 08:30
  • @Siddhi: Think of `new myInterface(){}` as instantiating a class that implements the interface without giving this class a name (aka anonymous class). The reason why you get output is because there's a main method. – James P. Jun 05 '10 at 11:01

4 Answers4

14

When you print out an object, it will call the toString() method. In the first statement, you create new object and also override method called toString. Therefore, this toString() method is called when object is printed.

In the second statement, you also create an object but you don't override the toString() method so that it will use the toString() method of the Object class.

For the new question, this link has a good explanation for your understanding: Anonymous Classes

Here is a copy of the explanation:

new className(optional argument list){classBody}

This expression instantiates a new object from an unnamed and previously undefined class, which automatically extends the class named className, and which cannot explicitly implement any interfaces. The body of the new class is given by classBody.

The result of executing this expression is that a new class that extends className is defined, a new object of the new class is instantiated, and the expression is replaced by a reference to the new object.

new interfaceName(){classBody}

This expression instantiates a new object from an unnamed and previously undefined class, which automatically implements the interface named interfaceName, and automatically extends the class named Object. The class can explicitly implement one, and only one interface, and cannot extend any class other than Object. Once again, the body of the new class is given by classBody.

Is it clear for you now?

Jim Ferrans
  • 30,582
  • 12
  • 56
  • 83
vodkhang
  • 18,639
  • 11
  • 76
  • 110
  • Okay... but this calls toString method as myAbstractClass is by default extends Object class... But if I use Interface instead of abstract class...it gives me same output...why it so..? – Siddhi Jun 05 '10 at 02:23
  • 2
    All objects either directly or indirectly, explicitly or implicity extends Object class. If you use an interface instead of an abstract class, then your anonymous classes will still implicitly extend Object. – emory Jun 05 '10 at 02:27
  • I already added a new, clearer explanation for anonymous class for interface. You should also look at the link, it is really good:) – vodkhang Jun 05 '10 at 04:11
  • Maybe because you are new and don't know the rule. But you can accept the answer – vodkhang Jun 05 '10 at 06:42
3

On the first println() you are overriding the toString() method from the anonymous myAbstractClass instance, therefore you get the string returned by your overriden toString() method, that's the default behavior of the println() function.

On the second println(), you are not overriding the toString() method, so println() uses the default one (inherited from Object).

On a side note, try formatting your code correctly, is much easier to read and understand.

abstract class myAbstractClass{}

public class Main { 
    public static void main(String[] args) { 
        System.out.println(new myAbstractClass(){
            public String toString(){
                return "myAbstractClass toString";
            }
        });

        System.out.println(new myAbstractClass(){
            public String myFunction(){
                return "myAbstractClass myFunction";
            }
        }); 
    } 
}
Cesar
  • 5,488
  • 2
  • 29
  • 36
  • Okay... but this calls toString method as myAbstractClass is by default extends Object class... But if I use Interface instead of abstract class...it gives me same output...why it so..? – Siddhi Jun 05 '10 at 02:26
  • 1
    Because any object instance you create, even if it's from a class implementing a interface, extends from Object. http://java.sun.com/javase/6/docs/api/java/lang/Object.html – Cesar Jun 05 '10 at 02:33
3

myAbstractClass is a minimal class. It inherits from object.

Class main constructs two anonymous inner classes from myAbstractClass, and prints their toString output.

  1. The inner class overrides the toString method and you see its output.
  2. The inner class get a method added, and you the the default toString definition.
BillThor
  • 7,306
  • 1
  • 26
  • 19
1

In both scenarios, you have printed the object. So it will call toString() method of the object. In the first scenario, since you have overridden the toString() method, so it is printing myAbstractClass toString. In the second scenario, since it was not overridden, it calls the default toString() implemented in the Object class.

I think you are expecting function call in the 2nd scenario which is wrong. You have just overridden it but never called.

Sujee
  • 4,985
  • 6
  • 31
  • 37