1. 程式人生 > >Java基礎十二--多態是成員的特點

Java基礎十二--多態是成員的特點

一個 開發 eth 類對象 要去 發生 方法 aide nbsp

Java基礎十二--多態是成員的特點

一、特點

1,成員變量。

編譯和運行都參考等號的左邊。

覆蓋只發生在函數上,和變量沒關系。

Fu f = new Zi();
System.out.println(f.num);//是父類,答案是3

2,成員函數(非靜態)。

編譯看左邊,運行看右邊。

因為成員函數存在覆蓋特性。

Fu f = new Zi();//
f.show();
輸出的是子類裏面的show方法

3,靜態函數。

編譯和運行都看左邊。

靜態函數不具備多態性,多態性是對象的多態性,然後靜態函數不涉及對象。

Fu f = new Zi();//
f.show();
這裏最後輸出的是父類的show裏面的內容。

Zi z = new Zi();//
z.show();

輸出的是子類裏面的show

二、實例

  1 /*
  2 多態時,
  3 成員的特點:
  4 1,成員變量。
  5     編譯時:參考引用型變量所屬的類中的是否有調用的成員變量,有,編譯通過,沒有,編譯失敗。
  6     運行時:參考引用型變量所屬的類中的是否有調用的成員變量,並運行該所屬類中的成員變量。
  7     簡單說:編譯和運行都參考等號的左邊。哦了。
  8     作為了解。
  9 覆蓋只發生在函數上,和變量沒關系。
 10 Fu f = new Zi();
 11 System.out.println(f.num);//是父類,答案是3
 12 沒根據f的值(子類對象的地址)去找,而是根據f的類型去找。
13 開發時不可能出現這樣的情況,我父類有了,我子類就直接拿來用了,而且用的時候一般都已經向下轉型了。 14 15 16 17 18 2,成員函數(非靜態)。 19 編譯時:參考引用型變量所屬的類中的是否有調用的函數。有,編譯通過,沒有,編譯失敗。 20 運行時:參考的是對象所屬的類中是否有調用的函數。 21 簡單說:編譯看左邊,運行看右邊。 22 23 因為成員函數存在覆蓋特性。 24 Fu f = new Zi();// 25 f.show(); 26 輸出的是子類裏面的show方法 27 依賴的是對象,有對象才有成員函數,必須動態的綁定到指定的對象上,所以運行的時候是看子類,而編譯的時候檢查語
28 29 法錯誤,所以編譯的時候檢查父類,所以看父類。 30 編譯檢查語法錯誤,運行時根據引用指向的地址運行。 31 32 33 34 35 3,靜態函數。 36 編譯時:參考引用型變量所屬的類中的是否有調用的靜態方法。 37 運行時:參考引用型變量所屬的類中的是否有調用的靜態方法。 38 簡單說,編譯和運行都看左邊。 39 40 其實對於靜態方法,是不需要對象的。直接用類名調用即可。 41 Fu f = new Zi();// 42 f.show(); 43 這裏最後輸出的是父類的show裏面的內容,因為靜態成員不需要對象,直接是被類名指向,都指向存靜態方法的方法區, 44 45 而那個裏面存的就是父類的show。 46 Zi z = new Zi();// 47 z.show(); 48 這裏的zi是繼承fu的,show方法是靜態的 49 輸出的是子類裏面的show 50 其實可以理解為靜態函數不具備多態性,多態性是對象的多態性,然後靜態函數不涉及對象 51 父類對象引用,就是指向父類的靜態函數 52 子類對象引用,就是指向子類的對象函數 53 54 55 56 57 */ 58 59 class Fu 60 { 61 // int num = 3; 62 void show() 63 { 64 System.out.println("fu show"); 65 } 66 67 static void method() 68 { 69 System.out.println("fu static method"); 70 } 71 } 72 73 class Zi extends Fu 74 { 75 // int num = 4; 76 void show() 77 { 78 System.out.println("zi show"); 79 } 80 81 static void method() 82 { 83 System.out.println("zi static method"); 84 } 85 } 86 87 88 89 class DuoTaiDemo3 90 { 91 public static void main(String[] args) 92 { 93 Fu.method(); 94 Zi.method(); 95 //這個的實質是父類對象指向子類引用,就是有點像指針,f的值是子類對象的地址。 96 Fu f = new Zi();// 97 // f.method();//輸出是父類的靜態 98 // f.show();//編譯的時候檢查的是父類,運行的時候以子類為主,show被覆蓋,運行的子類的show 99 //輸出是子類的show, 100 // System.out.println(f.num);//是父類,答案是3 101 102 103 // Zi z = new Zi(); 104 // System.out.println(z.num);//是子類,答案是4 105 } 106 }

三、內存儲存分析

Fu f = new Zi();

Fu f 在棧中定義了一個引用,也就是指針。

new Zi() 在堆中定義了一個對象,只不過這個對象有父類的那一部分成員。

1、如果用子類引用指向這個對象,全部訪問的是子類的。

2、如果用父類引用指向這個對象,全部訪問的是這個對象裏面父類的,只不過父類函數被覆蓋,所以導致成員是父類,函數時子類的。

肯定是根據指針類型去訪問要訪問的東西。貓肯定要去吃貓糧,狗才去吃狗糧。

Java基礎十二--多態是成員的特點