You could have just run the code by yourself, but here are the answers to each System.out.println() line in your and an explanation... System.out.println(A1.declaration2); - prints "This is ClassA:declaration2" Remember that variables are statically bound, therefore A1.declaration2 returns the member variable of A1's reference type, which is A. Therefore, from the initial declaration of declaration2, it prints out "This is ClassA:declaration2" System.out.println(A1.int1); - prints 2 To instantiate B, we used constructor chaining, thus B(2,3) calls super(2,3) which calls A(2,3). This sets int1 to 2. For the same reason as above, A1.int1 gets the int1 from A1's reference type, which is A. Therefore, we get 2. System.out.println(A1.getInt1()) - prints 3 Be careful here! Remember when we call methods, it calls the method according to the object type (dynamically bound). In this case, A1 references a B object, and therefore calls the getInt1() from the B class. Thus, since we passed in B(2,3) into the constructor, and then it increments both values by 1, we get 3. System.out.println(A1.int2) - prints 3 This is the same reasoning as System.out.println(A1.int2) System.out.println(A1.getInt2()) - prints 3 So according to all our reasoning, A1.getInt2() would call the getInt2() from the B class. But there is no getInt2() in the B class! If this occurs, Java moves up the hierarchy and searches for a getInt2() method. In this case, it moves up the A class and calls the getInt2() method. Therefore, getInt2() returns 3 (the value of int2 in the A class). System.out.println(A2.declaration1) - prints "This is ClassA:declaration1" This is a bit tricky. Remember that if we call a constructor from a subclass and it does not have this() or super() in it, then it automatically calls super(). This will set declaration1 from class A to "This is ClassA:declaration1". Since variables are statically bound, A2.declaration1 returns "This is ClassA:declaration1". System.out.println(((B)A2).declaration2) - prints "This is ClassB:declaration2" This is an explicit downcast. The downcast is legal since A2 points to a B object (but downcasting returns an error sometimes!). Therefore, it grabs declaration2 from the B class, and you get "This is ClassB:declaration2".