重寫方法在沒有多態的情況下,new的是哪個對象,就是調用的哪個類的方法,但是對于子父類同名成員變量卻不是
這是對我之前一篇博文的補充:關于子類和父類中的this的用法 - 明月鎮魂 - 博客園
之前博文里面都是有多態的情況,但是請看以下代碼:
public class Demo02 { public static void main(String[] args) { Zi zi =new Zi(); zi.show(); } } class Fu { public String num = "父類成員變量"; public void show() { System.out.println(this.num); System.out.println(this.fun1()); //System.out.println("父類方法"); } public String fun1() { System.out.println(this.num); return "父類調用"; } } class Zi extends Fu { public String num = "子類成員變量"; public String fun1() { System.out.println(this.num); return "子類調用"; } }
這里面是子類變量引用子類對象,沒有多態,最終的輸出結果是:
父類成員變量
子類成員變量
子類調用
現在zi調用show,然后調用里面的fun1方法,這種時候這里面的this誰來調用我,我就代表誰,其實就是根據創建的對象來決定調用的是哪個類的方法;
但是成員變量可不能這么解釋,在Java中,“成員變量的訪問是基于聲明類型的”這句話意味著當你在一個類的方法內部訪問某個成員變量時,Java會根據這個方法所在的類(即成員變量被聲明的那個類)來決定訪問哪一個成員變量,而不是根據對象的實際運行時類型。這與方法調用不同,方法調用可以根據實際對象的類型(多態性)來決定調用哪個版本的方法。
所以在java中,方法調用是動態綁定的(在這個例子中,盡管show()方法本身沒有被重寫,但我們談論的是如果它被重寫時會發生什么),但成員變量的訪問通常是靜態解析的(基于編譯時的類型信息)。在這個特定情況下,由于show()方法是在父類中定義的,并且沒有使用任何多態性來間接訪問變量(比如通過父類的引用指向子類對象并調用一個可能被子類重寫的方法),所以成員變量的訪問是靜態的,基于方法定義的位置。通俗解釋:在Java中,方法內部的成員變量訪問通常是基于編譯時類型的(這稱為“字段隱藏”的副作用),而不是運行時類型,有一個例外:如果通過方法調用(如this.someMethod())間接訪問成員變量,并且該方法被子類覆蓋,那么實際上調用的是子類的方法,而子類方法內部訪問的成員變量將基于子類的類型(這又是多態性的表現)。

浙公網安備 33010602011771號