Variables aren’t polymorphic. When you access m.name
, that will always use the Mammal.name
field which is part of that object, regardless of the execution-time type of the object. If you need to get access to Zebra.name
, you need an expression with a compile-time type of Zebra
.
The makeNoise
method is called virtually though – the implementation used at execution time does depend on the type of the object.
Note that if you make all your fields private – which is generally a good idea anyway – this doesn’t end up being an issue.
This is actually hiding rather than shadowing. See JLS section 8.3 for details on hiding, and section 6.4.1 for shadowing. I can’t say that I always keep the differences straight…