转: https://www.zhihu.com/question/41924954
下面代码的输出是什么?
实际结果是:
I am in B, value is 0
I am in B, value is 44
22
对这一结果我没有任何思路,不知道为什么,尤其是0.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class Test { public static void main(String[] args) { P b = new B(); System.out.println(b.a); } static class P { public int a = 11 ; public P() { a = 22 ; diplay(); } public void diplay() { System.out.println( "I am in P, value is " + a); } } static class B extends P { int a = 33 ; public B() { a = 44 ; diplay(); } public void diplay() { System.out.println( "I am in B, value is " + a); } } } |
解释1:
例子里,P.display()与B.display()构成覆写(override)关系:后者覆写前者。这是虚方法的多态性的表现。
所以在创建B类实例时,虽然会(显式或隐式)调用到P的构造器,但在P的构造器里调用的display()方法永远是按照虚方法的查找规则,找到该实例最准确的实现,所以P()里调用display()找到的是B.display()方法。
而字段永远不参与多态,哪个类的方法访问某个名字的字段时,该名字指的就是该类能看到的那个字段。当子类声明了与父类同名的字段时,虽然在子类里两个字段都会存在,但是子类的字段会遮蔽了父类的同名字段。
此例中,P.display()里访问“a”访问的是P.a,而B.display()里访问“a”访问的是B.a。
解释2:
首先,你的這個程序「翻譯」過來,是這樣的:(每個 a 的賦值實際都是在 constructor 裏執行的)
註釋裏的數字,是每一行發生的順序。
可以看到當09發生的時候,輸出的是 B 自己的 a,而這個 a 是一個成員變量,同時沒有被賦任何值,所以是 int 成員變量的 default value,即0。
public class Test {
public static void main( String [] args ) {
P b = new B(); // 01
System.out.println( b.a ); // 15
}
static class P {
public int a;
public P() { // 04
a = 11; // 05
a = 22; // 06
diplay(); // 07
}
public void diplay() {
System.out.println( "I am in P, value is " + a );
}
}
static class B extends P {
int a;
public B() { // 02
super(); // 03
a = 33; // 10
a = 44; // 11
diplay(); // 12
}
public void diplay() { // 08, 13
System.out.println( "I am in B, value is " + a ); // 09, 14
}
}
}
可以看到當09發生的時候,輸出的是 B 自己的 a,而這個 a 是一個成員變量,同時沒有被賦任何值,所以是 int 成員變量的 default value,即0。
标签:
java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!