构造器中的多态

[code="java"]
public class Parent {
private int eatId=0;
public Parent() {
System.out.println("parent is creating");
eat();
}
public void eat() {
System.out.println("==parent is eating "+eatId);
}
public static void main(String[] args) {
Parent p=new Son();
}
}

class Son extends Parent {
private int eatId=1;
public Son() {
System.out.println("son is creating");
eat();
}
public void eat() {
System.out.println("==son is eating "+eatId);
}
}
[/code]
如上代码,输出结果:
parent is creating //1
==son is eating 0 //2
son is creating //3
==son is eating 1 //4


疑惑的是,
1)输出中2 3行,为什么son在构造之前(按我的理解就是还没有生成)就可以调用它的eat方法了,如果可以调用这个时候的eatId是谁的,为什么?从结果看来是parent的 可是在parent中eatId是似有的啊?
2)eatId作为私有变量,parent中和son中有没有关系,他们存不存在重载的情况?

自己有点乱,请高人解释一下啊
[b]问题补充:[/b]
但是son 在还没有具体创建成功的时候 怎么能够调用他的方法呢?
RednaxelaFX 说的对,那个0不是表示parent 时表示jvm默认的初始赋值

楼主可能没理解的是,在Java中,一个类的所有方法的代码都是编译时就确定好的。一个类经由JVM加载后,其中所有的方法在任何时候都可以被调用。成员方法比较特别,因为它们有一个隐藏参数(this),而这个参数就是对象实例。

JVM构造对象实例是先分配空间(此时实例的所有状态介被默认初始化,也就是数字类型初始化为0,布尔类型初始化为false,引用类型初始化为null),再调用构造器。其中,构造器总是会通过基类的构造器来初始化实例中由基类的定义数据部分;即使用户写的构造器里没有显式调用基类的构造器,只要基类有默认构造器,就会在派生类构造器中第一行代码之前先调用基类的默认构造器;否则用户必须提供显式的对基类构造器的调用。
也就是说,调用构造器的时候,对象实例已经存在了,虽然其中的值还没有根据用户代码进行初始化。此时调用成员方法自然是可以的,只是状态很可能还没达到用户希望的初始状态而已。

例如在Java里写new Object(),编译为JVM字节码之后是:
[code="JVM bytecode"]new java/lang/Object // 创建实例
dup // 这个不用管,跟JVM的栈模型相关
invokespecial java/lang/Object.:()V // 调用构造器[/code]
观察到创建对象实例与调用构造器的动作是分开的。

1、在实例化son的时候优先调用了重载的parent的eat方法
这个时候的eatID是parent的,因为优先初始化parent的构造方法,这个时候再初始化变量,所以这里的eatID是parent的

2、私有变量在继承的时候没有重载

楼主把测试用的代码换成parent的eatID设为1,son的设为2再看看结果?
因为在构造son的时候需要先调用parent的构造器,此时son自己的eatID还没有被用户代码初始化,而是被JVM默认初始化为0,所以在parent的构造器里调用的son.eat()会看到0。注意到成员变量在Java里是没有多态一说的,多态只是对成员方法而言。