1
public class Test
{

    public static abstract class Node
    {
        private Node kid;
        public abstract int getN();
        public Node(Node kid) { this.kid = kid; }

        public final Node copyWithNewChild(Node newKid)
        {
            return new Node(newKid)
            {
                public int getN()
                {
                    return Node.this.getN(); //****
                }
            };
        }
    }
}

As you can see, I have this base class called Node, with a method getN() to be overriden by sub-classes.

Suppose I have a class called RedNode extending Node and providing a concrete implementation for getN(), and that I also have another class called SquareRedNode extending RedNodeand also providing an implementation for getN(). (And certainly, something else could also extend SquareRedNode (ie., the family tree could grow infinitely))

Now question, how does the compiler figure out which getN() to call when the copyWithNewChild() is executed?

(I'm not asking "what" implementation is being picked, which I can easily figure out by compiling/executing the code. I want to know how it is done.)

Thanks,

One Two Three
  • 22,327
  • 24
  • 73
  • 114
  • Every object has to carry a piece of data telling it what the actual *runtime* type is. At runtime, the program will need to look for this type information, and from there it can get information on which method to call. Perhaps my answer to http://stackoverflow.com/questions/21121256/how-does-java-call-objects-function might be helpful. – ajb Jan 14 '14 at 19:35
  • compiler doesn't know about it, it is being done at runtime – jmj Jan 14 '14 at 19:35
  • It's **not** done at compiling time. It's handled by JVM at run-time. – PM 77-1 Jan 14 '14 at 19:36

1 Answers1

4

The compiler doesn't figure it out, it's a virtual method and it doesn't get resolved until runtime.

The JVM looks at the class of the object it's calling getN on and sees if it implements getN. If it does, it uses it, otherwise it looks at the superclass and sees if it implements it. It proceeds up the class hierarchy this way until it finds an implementation.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • So even if the base class does provide an implementation for `getN()`, the statemetn `Node.this.getN()` would still not refer to `Node.getN()` but rather `ChildNode.getN()`? – One Two Three Jan 14 '14 at 19:41
  • @One: `Node.this` only refers to the outer object, it would still get the class on that object and start from there. (basically there's no way to skip over some subclass implementation other than overriding it.) – Nathan Hughes Jan 14 '14 at 19:54