By the rules of dynamic method binding, when you call printS1S2, on object of type S, the method in type R is executed. Now, with in that method, a call to printS1() at line 1, will call its (type R's) own private version of the method and not the one defined in S (had it been overridden with a widening modifier, the overridden method would get executed) and since printS2 is overridden, the overridden method in class S is executed and hence the result. Hope that helps.