Reputation: 1409
I ran into this example about inheritances on the web, and I am not easy regarding its results. I'm missing something critical.
public class A {
int i = 5;
public A() {
foo();
}
private void foo() {
System.out.println(i);
}}
public class B extends A {
int i = 6;}
public class C extends B {
int i = 7;
public void foo() {
System.out.println("C's foo");
System.out.println(super.i);
}}
I'm trying to figure out what's happening by the following command: C c = new C();
System.out.println(C.i);
I know that when we create a new instance of C
we approach A's and B's constructures, So We reach to A()
- (question 1) Does i
(of A) being initialize on the way?
Now we need to call to foo()
- (question 2)- Does C's foo()
consider as an override of A's foo()
? and what if B had a foo()
of itself? then it was consider as a override and C's foo()
was operated?
As far as I know, there is no override when it relates to local variables. How come that System.out.println(c.i)
is 7 and not 5? shouldn't it b the i
of the highest-father?
EDIT: My question is not about which foo and i will be used when I use c, is about what happens during these two specific commands, cause obviously A's foo was used and not C's.
Thank you very much.
Upvotes: 3
Views: 233
Reputation: 17622
About method overriding and visibility:
A.foo() is private. It means it's not visible to its subclasses. If you want B or C to override A.foo(), A.foo() needs to be protected or public. So in your code, B.foo() doesn't exist, because B doesn't know about A.foo().
Upvotes: 0
Reputation: 47759
A, B, and C each have an instance variable called "i". If you have a C object and execute foo() you will print C's value for "i".
If you had put foo() in B rather than C, oddly you'd still get C's value for "i" if you have a C object, since the "outermost" version of "i" will be used.
Upvotes: 0
Reputation: 3634
No, you always use the the class member closest to the class you've instantiated. So, C c = new C(); will use i=7 and C's foo only. Class B's i is overridden by class C's i, just as A's i has been overridden by B's i. There's no chaining going on, just overriding.
Upvotes: 0
Reputation: 1503449
The three i
variables here are completely independent. Which one is used by any statement is determined at compile-time - there's no polymorphism involved. So A.foo()
will always print out the value of the variable declared in A
.
Note that these aren't local variables by the way - they're instance variables.
When you print out c.i
that uses the variable declared in C
because the compile-time type of c
is C
. You can see this if you write:
C c = new C();
A a = c;
B b = c;
System.out.println(a.i); // 5 - variable declared in A
System.out.println(b.i); // 6 - variable declared in B
System.out.println(c.i); // 7 - variable declared in C
Note that in a well-written program this sort of thing almost never causes a problem, as variables should be private.
Upvotes: 5