The object is a B. It's then been assigned to a reference of type A (and you're allowed to do this because B extends A, which means a B IS-AN A), but the actual object is still a B. You can't change the type of an object once created, you can only assign it to different types of reference.
The other part to realise is that the B constructor will always call an A constructor. Since it doesn't to this explicitly (with a call to
super(...)), it calls the no-arg constructor. And that's why the answer isn't (b). You can explore this example further to understand how constructors call each other:
- Add the line
super(msg); at the beginning of the B constructor. Now the output will match (b).
- Comment out the no-arg constructor in A. No change, because the B constructor is calling the A constructor that takes a
String.
- Remove the
super() line you just added. Now it won't compile. With no call to super(), it'll try and call the no-arg constructor. But there isn't one!