下面我有两个班。父母和孩子。 Child类继承自Parent类。在Parent类构造函数中,我调用Parent类的print()方法。
当我在main()方法中为Child类创建Object时,运行Parent类构造函数并调用Child类print()方法而不是Parent类print()方法。
Q1。为什么会发生这种情况。
Q2。为什么i的值为0
public class Sample
{
public static void main(String[] args)
{
Child objChild = new Child();
objChild.print();
}
}
class Parent
{
void print()
{
System.out.println("i Value");
}
Parent()
{
print();
}
}
class Child extends Parent
{
int i = 45;
void print()
{
System.out.println("i Value = "+i);
}
}
OP
i Value = 0
i Value = 45
答案 0 :(得分:19)
调用子方法的原因是因为虚方法调度是Java中的标准。当您调用该方法时,它会根据对象的实际类型决定在运行时实际调用哪个方法。
至于它打印0的原因,那是因为i
尚未设置为45。每个字段都使用该类型的默认值进行初始化,在整数的情况下为0
。编写int i = 45
时,编译器将在构造函数中生成代码以设置i = 45
。但是在调用父构造函数之后它会将此代码放在中。因此,您在使用其预期值初始化变量之前打印变量。
答案 1 :(得分:10)
Java实际上有一些非常明确的规则。本质上,子类中的“int i = 45”代码是子类构造函数的隐式部分,超类构造函数始终首先运行。
事件的顺序是:
当你有一个最终的领域时,这真的很糟糕。您可以在示例中声明“i”final并获得相同的结果!
通常,在构造函数中调用非私有(或至少非最终)方法会遇到麻烦,并且通常是令人讨厌的错误的根源。调用抽象方法是一个非常坏主意(大部分时间)。
答案 2 :(得分:4)
Java初学者:我遇到了你的问题.. 1.当你创建子类的对象时,print()方法只在子类中调用,而不是在父类中,即使父类构造函数调用第一个bcoz,该对象是子类 请参考以下示例。
public class Test
{
public static void main(String[] args)
{
//create the object of child class
Child child = new Child();
}
}
class Parent
{
void print()
{
System.out.println("parent>> i ValueOne=");
}
Parent()
{
System.out.println("parent>> i ValueTwo=");
print();
}
}
class Child extends Parent
{
int i = 45;
void print()
{
System.out.println("Child>>i Value = "+i);
}
}
<强>输出强>:
parent>> i ValueTwo=
Child>>i Value = 0
2.如果此时创建父类对象,则调用父类中的print()方法。 请参考以下示例。
public class Test
{
public static void main(String[] args)
{
//create the object of Parent class
Parent parent = new Parent();
}
}
class Parent
{
void print()
{
System.out.println("parent>> i ValueOne=");
}
Parent()
{
System.out.println("parent>> i ValueTwo=");
print();
}
}
class Child extends Parent
{
int i = 45;
void print()
{
System.out.println("Child>>i Value = "+i);
}
}
<强>输出强>:
parent>> i ValueTwo=
parent>> i ValueOne=
3.我认为你已经清楚了为什么i的值是0或45。
答案 3 :(得分:2)
因为在第一次调用打印方法i
时没有初始化为45所以它的打印0。
电话就像这样
i
未初始化coz子构造函数尚未完成,因此打印默认值i
为0)i
获取其值为45 - 答案 4 :(得分:2)
首先,我没有在Child
类中看到构造函数定义。
如果没有为Child
类定义构造函数,则其默认构造函数为:
public Child() {
super();
}
super();
调用Parent
类构造函数(超类构造函数)。
但是,您在print()
类中定义了Child
方法,并且因为它与Parent
类中的方法具有相同的签名(名称+参数),所以它会覆盖其超类具有相同签名的方法。
这就是为什么你的Child
类调用Parent
类构造函数,而它调用自己的print()
方法。
- 增加:
第一个i值为0,因为您没有在i
类中初始化int变量Parent
,并且默认情况下未初始化的int变量的值为0。调用Parent
后,它会立即调用Child
的{{1}}方法,并在print()
类中初始化i
,所以现在Child
是您初始化的值
答案 5 :(得分:1)
您的孩子首先调用您父母的构造函数。此时,我没有使用45值初始化。这就是它打印0(默认的int值)的原因。