I am having some doubts about this Java code. The output it gives is "furry bray". My questions:
class Mammal { String name = "furry "; String makeNoise() { return "generic noise"; } } class Zebra extends Mammal { String name = "stripes "; String makeNoise() { return "bray"; } } public class ZooKeeper { public static void main(String[] args) { new ZooKeeper().go(); } void go() { Mammal m = new Zebra(); System.out.println(m.name + m.makeNoise()); //Output comes as "furry bray". Please explain this. //And how can we access the name variable, the one having "stripes " in it. //Does it have something to do with Variable Shadowing? } }
If the instance variable and local variable have same name whenever you print (access) it in the method. The value of the local variable will be printed (shadowing the instance variable).
Variable Hiding happens when a variable declared in the child class has the same name as the variable declared in the parent class. In contrast, variable shadowing happens when a variable in the inner scope has the same name as the variable in the outer scope.
How to avoid variable shadowing? To modify a global variable, and avoid variable shadowing python provides global keyword which tells python to use the global version of the variable, instead of creating a new locally scoped variable.
In Java, if there is a local variable in a method with the same name as the instance variable, then the local variable hides the instance variable. If we want to reflect the change made over to the instance variable, this can be achieved with the help of this reference. Example: Java.
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...
Output comes as "furry bray". Please explain this.
fields
in java programs are not accessed via dynamic lookup. Instead they are resolved statically while compile time. That's why you are getting furry
for m.name
. Whereas, methods
in java programs are accessed via dynamic lookup. That's why you are getting bray
for m.makeNoise()
.
And how can we access the name variable, the one having "stripes " in it?
And if you want to access Zebra.name
, you should type cast m
to 'Zebra'.This would look like this:
System.out.println(((Zebra)m).name + m.makeNoise());
UPDATE
The phenomena that is exhibiting here is the result of Fields Hiding rather than variable shadowing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With