Java programs have no direct access to memory so you should not concern yourself with memory questions. The memory implementaion may be specific to a Java VM implementation. However, I can outline a general process for you.
In order for this code to work, Sample1 class must be a descendant of Sample class. Each class is represented in memory by data (class member variables) and a vtable. Vtable is an array of pointers to virtual methods belonging to this class. For example, if Sample class is defined as follows:
public class Sample {
int var1;
int var2;
Sample() {}
public void method1() {}
public void method2() {}
}
it may be represented in memory like this:
vtable pointer<br />
var1<br />
var2
where vtable pointer points to this array of pointers to methods:
<br />
0: method1 from Sample class<br />
1: method2 from Sample class
If you have a descendant class Sample1 like this one:
public class Sample1 extends Sample {
int var3;
Sample1() {}
@Override
public void method1() {}
@Override
public void method2() {}
}
it will be represented in memory like this:
vtable pointer<br />
var1<br />
var2<br />
var3
where vtable pointer points to this array of pointers to methods:]
0: method1 from Sample1 class<br />
1: method2 from Sample1 class
When you create a Sample1 class instance with new, it will create the above memory structure for Sample1 class. When you assign it to a variable of Sample type:
Sample sample = new Sample1();
compiler will allow this because Sample1 class can be used as Sample class without problems. Indeed, a Sample1 class instance has the same variables (var1, var2) as the Sample class and at the same positions. As for Sample1 class vtable, it has the methods with the same signature and at the same positions as the Sample class. So you can safely work with Sample1 class through a Sample variable as it is compatible with it. I hope this explanation will help you.