4
public class A {
    public A() {
        foo();
    }

    private void foo() {
        System.out.print("A::foo ");
        goo();
    }

    public void goo() {
        System.out.print("A::goo ");
    }
}

public class B extends A {
public B() {
    foo();
}

public void foo() {
    System.out.print("B::foo ");
}

public void goo() {
    System.out.print("B::goo ");
}

    public static void main(String[] args) {

A b = new B() {
        public void foo() {System.out.print("Anonymous::foo ");}
        public void goo() {((B)this).foo();}
        };

}
}

I'd like your help with understanding why does the program print A::foo Anonymous::foo Anonymous::foo. Is this anonymous class replace the former B? overrides its methods?

As I see it, it should go to A's default constructor, run A's foo- print "A::foo", than run B's goo, since it was properly overrided, but now B's goo is the one in the Anonymous class, so it casts this to B (Which does nothing), and run its foo, which is the foo above, of B, so it should print "Anonymous:foo". What do I get wrong?

Thanks a lot.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
Numerator
  • 1,389
  • 3
  • 21
  • 40

4 Answers4

4

Your question isn't all that clear, but let me just say that the the answer would be exactly the same if instead of an anonymous class extending B, you had a top-level class C extending B. Nothing about anonymous classes makes them behave differently with respect to polymorphism and inheritance. When B's constructor calls foo(), the overriding version in the most-derived class -- here the anonymous class -- is invoked.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • Hi Ernest.Your'e saying that writing this anonymous class is like writing a class that extends from B? and it will be the dynamic type of b? – Numerator Sep 13 '11 at 14:14
  • upvoted, because the questioner specifically asked about anonymous inner classes, and this addresses that. – Nathan Hughes Sep 13 '11 at 14:19
4

I think the confusing thing here is you have two foo methods. One is private so it's not eligible for overriding, the other is public so it can be overridden. B is calling foo in its constructor but that's overridden by its subclass.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • I didn't understand why does it print what being printed, I wrote what I think it should do, and hoped for your corrections and explanations. I was misunderstood this anonymous class in this syntax. – Numerator Sep 13 '11 at 14:35
  • @Nir: is EFH's point helpful, that refactoring to give a name to the anonymous subclass produces the same result? i'd guess the anonymous inner class syntax is confusing the issue. – Nathan Hughes Sep 13 '11 at 14:39
3

A's constuctor calls A.foo (A::foo) because it is private and so not overloaded. A.foo calls goo() which was overridden by B and then by Anonymous so you get Anonymous.goo -> Anonymous.foo (Anonymous::foo). Then B's constructor calls foo which is overridden by Anonymous so (Anonymous::foo)

John B
  • 32,493
  • 6
  • 77
  • 98
1

Using that kind of anonymous construction in fact creates a subclass of B. You have overridden B's methods with the ones you provide in the anonymous class so those will be used instead.

  • Jonathan Weatherhead, On my own experience and suffering you are right, that is exactly what’s going on. But I could not find this behavior explained anywhere on the “official” documentation. Could you help finding it? Where did you get this piece of information from? – Legna Oct 18 '11 at 19:09