Originally posted by Jim Sandman:
(others pls correct me if wrong, but...)
The reason the output is: R.printS1 S.printS2
"R.printS1" prints because the instantiated class S (a subclass of R) calls the protected printS1S2 method of R.
"S.printS2" prints because the printS2 method of S overrides the printS2 method of R.
This is correct. These facts should explain the confusion a bit
1. R#printS1() is not overridden by S.
"R.printS1" will print because as defined in the superclass R, printS1() is a private method, not a protected one. Any method that is of private access can't be seen by its subclasses, and therefore can't be overridden (nor hidden, nor overloaded). As far as each class is concerned, they each just happen to have private helper methods with the same signature.
2. S#printS2() successfully overrides R#printS2
Why? Because R#printS2 is a protected member, and therefore inherited by S. Because it isn't final or static, S overrides it without issue and the behavior of the method for all instances of S() will invoke S#printS2() when calling printS2().
3. R#printS1S2 is never overridden at all
Because printS1S2's implementation only exists in R, any non-overridden methods will be invoked just as they would if the instance's most specific type was R.
Based on the third observation, you can see that what's really happening under the covers when:
are invoked is:
What the compiler sees is--from the context of printS1S2() in R--a private method in R and an instance method of R overridden by S.
That's my stab at explaining why it will read "R.printS1 S.printS2"
[ July 11, 2007: Message edited by: Justin Searls ]