java - 继承中如何初始化父子字段?
问题描述
我面临着一种困惑。
这是我的小代码片段
public class Father {
public String x;
public Father() {
this.init();
System.out.println(this);
System.out.println(this.x);
}
protected void init() {
x = "Father";
}
@Override
public String toString() {
return "I'm Father";
}
void ParentclassMethod(){
System.out.println("Parent Class");
}
}
public class Son extends Father {
public String x;
@Override
protected void init() {
System.out.println("Init Called");
x = "Son";
}
@Override
public String toString() {
return "I'm Son";
}
@Override
void ParentclassMethod(){
super.ParentclassMethod();
System.out.println("Child Class");
}
}
public class MainCLass{
public static void main(String[] args){
Son ob = new Son();
}
所以当我创建一个继承自父类的子类实例时,JVM会自动调用父类的构造函数。当父亲的构造函数被调用时,它会创建 Son 类型实例,否则父亲的字段不会被初始化。到目前为止好..!
如您所见,字段x
是从父亲的类派生到儿子的类中的。我的代码x
使用init()
方法初始化。
那为什么它显示为空。
它非常混乱。谁能解释一下?
解决方案
Java中的变量不是多态的。x
由于您在 inside重新声明Son
,因此该变量实际上与 in 中的变量不同 。所以在 of 的方法中,你正在初始化's ,而不是' s 。x
Father
init
Son
Son
x
Father
x
另一方面,您的语句System.out.println(this.x);
在Father
类内,因此它只知道Father
's x
。由于重写该init
方法,您不再初始化此变量,因此x
inFather
保留null
(默认),因此它将打印null
.
您可以通过public String x;
从Son
班级中删除来解决问题。这将使Father
'sx
唯一的x
,消除问题。
但是,通常,您希望使用此变量private
而不是public
. 你也不应该final
在构造函数中调用非方法。它只能引入错误。在这种情况下,初始化它的正确方法是使用带有 in 参数的构造函数Father
:
public class Father {
private String x;
protected Father(String x) {
this.x = x;
System.out.println(this);
System.out.println(this.x);
}
public Father() {
this("Father");
}
// Rest of father's code, without the init method
}
public class Son extends Father {
public Son() {
super("Son");
}
// Rest of son's code, without the init method
}
推荐阅读
- tags - Add specific tags to specifi products in a shopify
- javascript - 使用 for-of 更新数组对象
- c# - 下拉列表更改事件未在更新面板中触发
- sonarqube - 在 Sonarqube 社区版中停用规则
- aspectj - 在类加载器从其他 jar 文件 AspectJ 加载之后在运行时加载类
- php - 未下载的 EXCEL 文件名称中包含 #(hash) 符号
- php - 如何使用包含全局变量的查询正确定义全局变量?
- sql-server - 存储为字符串、枚举或 SQL 数据库中的另一个表?
- java - java.lang.RuntimeException:布局不能为空。调用 setLayout
- angular - Bootstrap 4 模态在电子中不起作用