javabindingoverloadingmethod-dispatch

Java dynamic binding


I am practicing for an exam, and found a sample problem that gets me totally lost. For the following code, find what the output is:

class Moe {
    public void print(Moe p) {
        System.out.println("Moe 1\n");
    }
}
class Larry extends Moe {
    public void print(Moe p) {
        System.out.println("Larry 1\n");
    }
    public void print(Larry l) {
        System.out.println("Larry 2\n");
    }
}
class Curly extends Larry {
    public void print(Moe p) {
        System.out.println("Curly 1\n");
    }
    public void print(Larry l) {
        System.out.println("Curly 2\n");
    }
    public void print(Curly b) {
        System.out.println("Curly 3\n");
    }
}
public class Overloading_Final_Exam {
    public static void main (String [] args) {
        Larry stooge1 = new Curly();
        Moe stooge2 = new Larry();
        Moe stooge3 = new Curly();
        Curly stooge4 = new Curly();
        Larry stooge5 = new Larry();
        stooge1.print(new Moe()); 
        ((Curly)stooge1).print(new Larry()); 
        ((Larry)stooge2).print(new Moe()); 
        stooge2.print(new Curly()); 
        stooge3.print(new Curly()); 
        stooge3.print(new Moe()); 
        stooge3.print(new Larry()); 
        ((Curly)stooge3).print(new Larry()); 
        ((Curly)stooge3).print(new Curly()); 
        stooge4.print(new Curly()); 
        stooge4.print(new Moe()); 
        stooge4.print(new Larry()); 
        stooge5.print(new Curly()); 
        stooge5.print(new Larry()); 
        stooge5.print(new Moe()); 
    }
}

I had my ideas in mind, but then when I ran the java, I got something totally different:

Curly 1
Curly 2
Larry 1
Larry 1
Curly 1
Curly 1
Curly 1
Curly 2
Curly 3
Curly 3
Curly 1
Curly 2
Larry 2
Larry 2
Larry 1

The first few ones are OK, but then I really don't understand. Anyone has a good explanation for this problem?

Thanks


Solution

  • I would start by drawing a picture...

    Moe - print(Moe)
     |
    Larry - print(Moe), print(Larry)
     |
    Curly - print(Moe), print(Larry), print(Curly)
    

    Then I would keep track of the variables:

    etc...

    Let me know if following that all the way through doesn't work out for you.

    (updated to clarify the next one)

    So the general rule is:

    So when you have:

    Moe stooge2 = new Larry();
    stooge2.print(new Moe());
    

    the compiler says:

    the runtime says:

    Once you have worked all that out try getting rid of some of the methods and see how that changes things.