0

Consider the following code.

class Base {
    int i = 99;

    public void amethod() {
        System.out.println("Base.amethod()");
    }

    Base() {
        this.amethod();
    }
}

public class Derived extends Base {
    int i = -1;                                      
    public static void main(String argv[]) {
        Derived  b;                       // here if we use **Base b;** below mentioned println() prints 99 
        b = new Derived();                
        System.out.println(b.i);                   
        b.amethod();
    }

    public void amethod() {
        System.out.println("Derived.amethod()");
    }
} 

output that i get

Derived.amethod()
-1              (99 when reference variable is of Base type)
Derived.amethod()

Now my question is

Since I am using only one 'new' keyword, only one object will get created (Which would be an instance of both Derived and base class),this object will have a single instance variable named i whose value should be same(as i think) whether one references it using Base class ref var or Derived class ref var.So how this i's value gets changed just by changing reference variable declaration(from Derived to Base) because i'm not changing anything in heap where objects get stored.

Hope I am clear in putting my question.

SatyaTNV
  • 4,137
  • 3
  • 15
  • 31
Deepankar Singh
  • 662
  • 1
  • 9
  • 20

2 Answers2

3

There is one object, yes, but it has two members called i. Basically the one in Derived shadows the one in Base. Member access is not polymorphic - it refers to the exact member of the type relevant to the reference pointing at the object.

mszymborski
  • 1,615
  • 1
  • 20
  • 28
  • This sounds a bit strange to me. Can a single Derived instance have two field with the same name i?Please elaborate. – Deepankar Singh Sep 17 '15 at 19:13
  • Sure it can! Imagine that you write a class which extends a class from some obscure library. Now deep down in the inheritance chain there's some member called `i` or something more common. More than that that variable is also, as in your example, package-protected - but your class is not in the package. Would it be reasonable to disallow you to make a member `i`? Not really. You shouldn't care about what happens deeper. You can tune up warnings to allow you to spot such unfortunate events as you have experienced. – mszymborski Sep 17 '15 at 19:17
1

When you instantiate a Derived, you will actually have two class fields named 'i'. But one will be Base.i, and the other Derived.i The Derived field will hide the Base field unless, as you saw, your Derived is being treated as a Base

ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
  • This sounds a bit strange to me. Can a single Derived instance have two field with the same name i?Please elaborate. – Deepankar Singh Sep 17 '15 at 19:12
  • The reality is that field names are mostly (almost entirely) for legibility of code. Understand that when the class is compiled and executed, these variable names no longer 'almost' exist (can still be accessed through reflection though) and are replaced by a block of memory in the heap, where fields are accessed through an offset on this block. The rest is just language syntax about allowing / disallowing this kind of overloading, and what the proper implementation of this case is. Hope that explains things somewhat. – ControlAltDel Sep 17 '15 at 19:25