Deepankar Singh
Deepankar Singh

Reputation: 674

What is the difference between these two declaration of anonymous class

I'm not able to find differences between these two declaration of anonymous class.

class Boo {
       Boo(String s) { }
       Boo() { }
    }
    class Bar extends Boo {
       Bar() { }
       Bar(String s) {super(s);}
       void zoo() {
           Boo f = new Boo() {                       // Line-1
               void method()
               {
                   System.out.println("Inside anonymous");
               }
           };
       }
    }


class Boo {
       Boo(String s) { }
       Boo() { }
    }
    class Bar extends Boo {
       Bar() { }
       Bar(String s) {super(s);}
       void zoo() {
           Boo f = new Boo("Random String") {         // Line-2
               void method()
               {
                   System.out.println("Inside anonymous");
               }
           };
       }
    }


Here what i understood is, anonymous class is subclass of class Boo whose instance is polymorphically referred by reference variable f. But what difference it makes in using no-args constructor (Line-1) and parametrized constructor (Line-2).

Upvotes: 1

Views: 80

Answers (2)

RealSkeptic
RealSkeptic

Reputation: 34608

Let's add some "meat" to your classes to see what the difference is. Change Boo so that it actually does something with the string:

class Boo {
    private String s = "Default";

    Boo(String s) {
        this.s = s;
    }

    Boo() {
    }

    protected String getString() {
        return s;
    }
}

Now it stores the string, and any subclass can retrieve that string via the getString() method.

Now expand our Bar:

class Bar extends Boo {
    Bar() {
    }

    Bar(String s) {
        super(s);
    }

    void zoo() {
        Boo anon1 = new Boo() {                       // Line-1
            void method()
            {
                System.out.println("Inside anonymous");
            }
            @Override
            public String toString() {
                return "First anonymous subclass of Boo with value " + getString();
            }
        };
        Boo anon2 = new Boo("Some Random Value") {    // Line-2
            void method()
            {
                System.out.println("Inside anonymous");
            }
            @Override
            public String toString() {
                return "Second anonymous subclass of Boo with value " + getString();
            }
        };
        System.out.println(anon1);
        System.out.println(anon2);
    }
}

So I created the two types of anonymous classes inside the same method, and then I print them. Note that I have added a toString method to each of the anonymous classes. And the toString method uses the getString from Boo in the value it returns.

Now, what happens when you call new Bar().zoo()?

You get the output

First anonymous subclass of Boo with value Default
Second anonymous subclass of Boo with value Some Random Value

So the first object, anon1 is created with Boo's no-args constructor. Therefore the private s has the value Default. This reflects in the toString() method. The second object is created with Boo's other constructor, that gives s a different value. Now that value becomes part of the value printed.

So when the constructors actually do something, and the anonymous class makes use of the information that was passed in the constructor, then it makes a difference if you pass a parameter or not.

Notes

  • Bar itself is also a subclass of Boo but in your example, it makes no difference. It could be a completely independent class.
  • The method method() is never used and cannot be used (except with reflection etc.) because the only reference to the anonymous class is through type Boo which doesn't have an inheritable method(). You can't call a subclass's method from a superclass reference unless the method is inherited or overridden.

Upvotes: 2

Suresh Atta
Suresh Atta

Reputation: 121998

  • It notes that Boo have multiple constructors defined in it.

And

 Boo f = new Boo("Random String") {         // Line-2
               void method()
               {
                   System.out.println("Inside anonymous");
               }
           };

Since it is an annonymous class, and provided the implementation right away, there is no one using that string and that string passing is redundant there.

Upvotes: 3

Related Questions