Reputation: 682
GIVEN:
class A
{
String s = "A";
}
class B extends A
{
String s = "B";
}
public class C
{
public static void main(String[] args){ new C().go();}
void go()
{
A a = new B();
System.out.println(a.s);
}
}
Question:
What are the mechanics behind JVM when this code is run? How come a.s prints back as "A".
Upvotes: 4
Views: 234
Reputation: 18045
Although member variables are inherited from a base class, they are not invoked polymorphically (i.e dynamic invocation does not apply to member variables).
So, a.s will refer to the member in the base class and not the derived class.
Having said that, the code is not following OO principles. The members of a class need to be private/protected (not public or default) depending on the business use case and you need to provide public methods to get and set the values of the member.
Upvotes: 0
Reputation: 346526
You probably expect fields to be overridden like method, with dynamic dispatch based on the runtime type of the object.
That's not how Java works. Fields are not overridden, they are hidden. That means an object of class B has two fields named "s", but which of them is accessed depends on the context.
As for why this is so: it wouldn't really make sense to override fields, since there is no useful way to make it work when the types are different, and simply no point when the type is the same (as you can just use the superclass field). Personally, I think it should simply be a compiler error.
Upvotes: 2
Reputation: 597382
This isn't polymorphism (as tagged).
Java has virtual methods, not virtual member variables - i.e. you don't override a property - you hide it.
Upvotes: 1
Reputation: 91931
Field references are not subject to polymorphism, so at compile time the compiler is referencing A's field because your local variable is of type A.
In other words, the field behavior is like the Java overloading behavior on methods, not the Java overriding behavior.
Upvotes: 4