When we create an instance of A and pass an instance of B to its constructor, we are creating a Thread object from Runnable B (using the call to super), but we're still calling start on Thread object A. And although we created our Thread object using Runnable B, the Thread object is A, and A has overridden Threads's run method.
If A did not override run, then the parent (Thread's) version of run would be called. In the API for Thread's run method, it states, "If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns." Therefore, because A was constructed using a separate Runnable object, B's run method would be called.
In other words, Thread's run behavior is to use the Runnable's run method if a Runnable instance (B) is provided in the constructor. However, if run is overridden, then the overridden version of run (in A) is invoked rather than the version of run in the parent class Thread (which would invoke B's run). [ September 14, 2004: Message edited by: marc weber ]
"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer sscce.org
I believe the answer is polymorphism, although may be wrong.
Look at it this way, you are calling the thread constructor passing in a class which implements Runnable. This tells the thread class- we have a thread to run- <i>when you are asked to initiate a thread, you are going to invoke your own run method which will invoke the run method on this passed in class</i>. Italics indicate I am guessing actually.
Now you <i>also implement a version of public void run()</i>. This is an override. In a polymorphic call- it will invoke your version rather than the base class version.
In the first version, you have an overridden method. The dynamic binding occurs on the .start and it invokes the run() method. Which run? The base class run method, or the derive class run method? Well- you overrode it, and it actually is of that type, so it is calling the overridden version, and prints out A.
In the second version, you DO NOT have an overrridden method. There is no dymanic binding- it calls the only version of run it knows of. It calls in fact- the version which invokes run on the runnable interface you passed in. This prints out B.
I am guessing but it seems reasonable. The question really is- what exactly is going on within start?
Originally posted by Tom Tolman: I believe the answer is polymorphism, although may be wrong.
I think you're correct, although my post above probably does a poor job of explaining.
Because A was created with a Runnable object B, Thread's version of run will invoke B's implementation of run. However, because the extending class (A) overrides run, Thread's implementation of run isn't invoked at all (and therefore B's version of run isn't invoked).
:roll: [ September 14, 2004: Message edited by: marc weber ]