I don't get it, why the answer is not "Sub2 2" - as ga is object of Arabik class and Arabik sets i to 2 on object creation.
I know that the result is "Sub1 2" - checked in compiler, but why?
Hi "Egowmaster",
It's true that i comes from ga which is a Greek type variable that refers to an instance of Arabik:
Greek ga=new Arabik();
However, this does NOT override the variable i.
Let me first talk about getI() method, before we come to the variable i - I think it makes the explanation further clearer.
When we call getI() method, it first checks if that method exists on Greek, but actually calls that method from Arabik instance because of something called polymorphism At compile time, it first checks if getI() method exists in the reference type, which is Greek. If the method did not exist in that class, it will not compile at all. However, even though the compiler checks that method on the reference type, it will be different in runtime, and will actually call getI() on Arabik instance because of polymorphism.
This whole story of polymorphism plays only with methods, and does NOT play with instance variables at all. That said, when you access an instance variable on a reference variable (as i on ga), instance variables are always accessed from the reference type.
Consider these:
Greek ga = new Arabik();
print(ga.i); // prints 1
print( ((Arabik)ga).i ); // prints 2 (this time, you casted it to Arabik, so that's the reference type the compiler sees.
It only works with the reference type, and doesn't care if i exists in Arabik at all.
So that answers your question, got it?
As you are preparing for the exam, let's go little bit further beyond your question and see what happens if we do the same with methods...
print( ga.getI() ); // prints 2 print( ((Arabik)ga).getI() ); // prints 2
As you can see, it will always call the method from Arabik. So, what would happen if we remove getI() from Greek?
print( ga.getI() ); // compile error print( ((Arabik)ga).getI() ); // prints 2
The first line gives a compile error this time, because the compiler only looks at getI() method in the reference type. It can't find it means it will not compile.
Now what if we leave the method in Greek (without removing) and remove it from Arabik?
print( ga.getI() ); // prints 1 print( ((Arabik)ga).getI() ); // prints 1
This time, the compiler is okay as it finds the method in the reference type (Greek). At runtime, since the method is not available in the actual object Arabik, it calls the inherited method in Greek class.