java 在构造函数中调用方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16183831/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling methods inside Constructor
提问by Java Beginner
Below I am Having Two classes.Parent and Child. The Child class inherits from Parent class .In Parent class constructor I am calling print() method of Parent class.
下面我有两个班级。父级和子级。Child 类继承自 Parent 类。在 Parent 类构造函数中,我正在调用 Parent 类的 print() 方法。
When I create Object for Child class in main() method the Parent class constructor runs and the Child class print() method is called instead of Parent class print() method.
当我在 main() 方法中为 Child 类创建 Object 时,父类构造函数会运行,并且会调用 Child 类的 print() 方法而不是父类的 print() 方法。
Q1. Why this Happens.
一季度。为什么会这样。
Q2. Why the value of i is 0
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
采纳答案by Antimony
The reason the child method is called is because virtual method dispatch is the norm in Java. When you call the method, it decides which method to actually call at runtime based on the actual type of the object.
调用子方法的原因是因为虚拟方法调度是 Java 中的规范。当您调用该方法时,它会根据对象的实际类型决定在运行时实际调用哪个方法。
As for why it prints 0, that's because i
hasn't been set to 45 yet. Each field is initialized with a default value for that type, 0
in the case of integers. When you write int i = 45
, the compiler will generate code in the constructor to set i = 45
. But it places this code afterthe parent constructor is called. Therefore, you're printing the variable before it is initialized with its intended value.
至于为什么打印0,那是因为i
还没有设置成45。0
在整数的情况下,每个字段都使用该类型的默认值进行初始化。编写时int i = 45
,编译器会在构造函数中生成代码来设置i = 45
。但是它会在调用父构造函数之后放置这段代码。因此,您要在使用预期值初始化变量之前打印变量。
回答by john_omalley
Java actually has some pretty clear rules about this. Essentially the "int i = 45" code in the subclass is an implicit part of the subclass constructor and the superclass constructor alwaysruns first.
Java实际上对此有一些非常明确的规则。本质上,子类中的“int i = 45”代码是子类构造函数的隐式部分,而超类构造函数始终首先运行。
The order of events is:
事件的顺序是:
- Create the object and zero out all instance variables.
- Invoke superclass initializers.
- Invoke superclass constructor.
- Invoke subclass initializers (int i = 45; in this example)
- Invoke subclass constructor.
- 创建对象并将所有实例变量清零。
- 调用超类初始值设定项。
- 调用超类构造函数。
- 调用子类初始值设定项(int i = 45;在本例中)
- 调用子类构造函数。
This gets really nasty when you have a final field. You could declare "i" final in your example and get the same result!
当您有最后一个字段时,这会变得非常糟糕。您可以在示例中将“i”声明为 final 并获得相同的结果!
In general, invoking non-private (or at least non-final) methods in a constructor is asking for trouble and is often the source of nasty bugs. Invoking an abstract method is a reallybad idea (most of the time).
一般来说,在构造函数中调用非私有(或至少是非最终)方法是自找麻烦,并且通常是令人讨厌的错误的根源。调用抽象方法是一个非常糟糕的主意(大多数情况下)。
回答by vijayk
Java Beginner: I got your problem.. 1.When you create the object of child class at that time print() method called only in child class not in parent class even though parent class constructor called first bcoz the object is of child class Please refer the following example.
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);
}
}
output:
输出:
parent>> i ValueTwo=
Child>>i Value = 0
2.If you create the parent class object at that time the print() method in parent class is called. Please refer the following example.
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);
}
}
output:
输出:
parent>> i ValueTwo=
parent>> i ValueOne=
3.And i think you have already cleared why that value of i is 0 or 45.
3.我想你已经清楚为什么 i 的值是 0 或 45。
回答by exexzian
Because at that time of first call to print method i
is not initialized to 45 so its printing 0.
call goes like this
因为当时第一次调用print方法i
没有初始化为45所以它打印0.
调用是这样的
- child constructor (as because of constructor chaining from child to parent)
- parent constructor
- print method (now here
i
is not initialized coz child constructor is not complete yet so its printing the default value ofi
which is 0 ) - now after completion of parent constructor and then child constructor
i
gets its value which is 45 - - so now it prints 45 on the next call of print method
- 子构造函数(因为从子到父的构造函数链接)
- 父构造函数
- 打印方法(现在这里
i
没有初始化,因为子构造函数还没有完成,所以它打印的默认值为i
0 ) - 现在在父构造函数完成后,然后子构造函数
i
得到它的值为 45 - - 所以现在它在下一次调用 print 方法时打印 45
回答by Eric Na
First, I do not see the constructor definition in your Child
class.
首先,我没有在您的Child
类中看到构造函数定义。
When you do not define a constructor for a Child
class, its default constructor is:
当你没有为一个Child
类定义构造函数时,它的默认构造函数是:
public Child() {
super();
}
Where super();
calls the Parent
class constructor(super class constructor).
其中super();
调用Parent
类构造函数(超类构造函数)。
However, you defined your print()
method in Child
class, and since it has the same signature(name+parameter) as the method in Parent
class, it overrides its super class method with the same signature.
但是,您print()
在Child
类中定义了方法,并且由于它与类中的方法具有相同的签名(名称+参数)Parent
,因此它会使用相同的签名覆盖其超类方法。
That is why your Child
class calls Parent
class constructor, while it calls its own print()
method.
这就是为什么你的Child
类调用Parent
类构造函数,而它调用自己的print()
方法。
-added:
-添加:
The first i value is 0 because you did not initialize an int variable i
in Parent
class, and the value of an uninitialized int variable is 0 by default. After Parent
is called, it invokes now Child
's print()
method, and i
is initialized in Child
class, so now i
is the value you initialized
第一个 i 值为 0,因为您没有i
在Parent
类中初始化 int 变量,而未初始化的 int 变量的值默认为 0。之后Parent
被调用,它现在调用Child
的print()
方法,并i
在初始化Child
类,所以现在i
是你初始化值
回答by Pol0nium
Your child first calls your parent's constructor. At this point, i isn't initialized with the 45 value. That's why it prints 0 (the default int value).
你的孩子首先调用你父母的构造函数。此时, i 未使用 45 值进行初始化。这就是它打印 0(默认 int 值)的原因。