Numerator
Numerator

Reputation: 1409

Inheritances in Java

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

Answers (4)

TotoroTotoro
TotoroTotoro

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

Hot Licks
Hot Licks

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

Jim Barrows
Jim Barrows

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

Jon Skeet
Jon Skeet

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

Related Questions