//src/com/test/animal/Animal.java
package com.test.animal;
public class Animal
{
Animal()
{
init();
}
public void init()
{
System.out.println("parent init()");
}
}
//src/com/test/animal/Dog.java
package com.test.animal;
public class Dog extends Animal
{
String name = null;
Dog()
{
super();
}
public void init()
{
System.out.println("child init()");
super.init();
name = new String("dog");
System.out.println("name: "+name);
}
public static void main(String[] args)
{
Dog d = new Dog();
System.out.println("name: "+d.name);
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
child init()
parent init()
name: dog
name: null
Run Code Online (Sandbox Code Playgroud)
似乎调用了子中的init(),但是没有保存NAME值!为什么?如果我将NAME移动到父级,那就没关系.然而,保留在孩子身上更合理,因为它是特定于狗的.
另外,我可以在child的构造函数中显式调用init()来解决这个问题.这不是那么好.
执行的顺序如下:
Dog
构造函数被调用.Animal
构造函数.Animal
构造函数调用的init
方法.因为它被覆盖Dog
,所以Dog
调用版本.Dog.init
你设置name
为"dog"
.Dog.init
方法返回.Dog
初始化成员变量.这将设置name
为null
.结果:name
将是null
.
一个很好的例子,说明为什么你不应该调用可以从构造函数中重写的方法 - 因为它会导致像这样的惊喜.
旁注:永远不要这样做:
// Unnecessarily creating a new String object
name = new String("dog");
Run Code Online (Sandbox Code Playgroud)
只需这样做:
name = "Dog";
Run Code Online (Sandbox Code Playgroud)
永远不必String
从字符串文字中显式创建新对象.