黑馬程序員——Java面向對象——多態

面向對象

多態:

多態的概述:某一類事物的多種存在的多種形態。

1,多態的體現

父類的引用指向了自己的子類對象。

父類的引用也可以接收自己的子類對象。

2,多態的前提

必須是類與類之間有關係。要麼繼承,要麼實現。

通常還有一個前提:存在覆蓋。

3,多態的好處

多態的出現大大的提高程序的擴展性。

4,多態的弊端

提高了擴展性,但是隻能使用父類的引用訪問父類中的成員。

5,多態的應用

  1. abstractclass Animal {
  2.         public abstractvoid eat();
  3. }
  4. class Cat extends Animal  {  
  5.         public void eat(){  
  6.                 System.out.println("喫魚");  
  7.         }  
  8.         public void catchMouse()  {  
  9.                 System.out.println("抓老鼠");  
  10.         }  
  11. }  
  12. class Dog extends Animal  {  
  13.         public void eat()  {  
  14.                 System.out.println("喫骨頭");  
  15.         }  
  16.         public void kanJia()  {  
  17.                 System.out.println("看家");  
  18.         }  
  19. }  
  20. class Pig extends Animal  {  
  21.         public void eat()  {  
  22.                 System.out.println("飼料");  
  23.         }  
  24.         public void gongDi()  {  
  25.                 System.out.println("拱地");  
  26.         }  
  27. }  
  28.   
  29. class DuoTaiTest   {  
  30.         public static void main(String[] args)   {  
  31.                 Animal a = new Cat();
  32.                 //類型提升。 向上轉型。 父類類型指向子類對象 
  33.                 a.eat();  //喫魚
  34.   
  35.                 //如果想要調用貓的特有方法時,如何操作?  
  36.                 //強制將父類的引用。轉成子類類型。向下轉型。  
  37.                 Cat c = (Cat)a;  
  38.                 c.catchMouse(); //抓老鼠
  39.   
  40.                 //不要出現這樣的操作,就是將父類對象轉成子類類型。  
  41.                 //我們能轉換的是父類應用指向了自己的子類對象時。
  42.                 //該應用可以提升,也可以被強制轉換。  
  43.                 //多態自始至終都是子類對象在做着變化。  
  44.                 //      Animal a = new Animal();  
  45.                 //      Cat c = (Cat)a;  
  46.                   
  47.   
  48.                 /* 
  49.                 父 x = new 子(); 
  50.                 x.工作(); 
  51.                 子 y = (子)x; 
  52.                 y.玩(); 
  53.                 */  
  54.                 function(new Cat());
  55.                 function(new Dog());  
  56.                 function(new Pig());  
  57.   
  58.   a instanceof animal
  59.             }  
  60.             public static void function(Animal a){//Animal a = new Cat();  
  61.                 if(!(a instanceof Animal)) { 
  62.                     System.out.println("類型不匹配"); 
  63.                 } 
  64.                 else{
  65.                         a.eat();
  66.                         if(a instanceof Cat)   
  67.                                 Cat c = (Cat)a;  
  68.                                 c.catchMouse();  
  69.                         }
  70.                         else if(a instanceof Dog)  {  
  71.                                 Dog c = (Dog)a;
  72.                                 c.kanJia();
  73.                         }
  74.                        else if (ainstanceof Pig()){
  75.                                 Pig p = (Pig)a;
  76.                                 a.gongDi();
  77.                         }
  78.                 }
  79.                 //instanceof : 用於判斷對象的類型。 
  80.                //對象 intanceof 類型(類類型 接口類型)   
  81.            }  
  82. }  

 多態==晚綁定

  不要把函數重載理解爲多態。

  因爲多態是一種運行期的行爲,不是編譯期的行爲。

  多態:父類型的引用可以指向子類型的對象。

  比如 Parent p = new Child();

    當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;

    如果有,再去調用子類的該同名方法

  (注意此處,靜態static方法屬於特殊情況,靜態方法只能繼承,不能重寫Override,如果子類中定義了同名同形式的靜態方法,它對父類方法只起到隱藏的作用。調用的時候用誰的引用,則調用誰的版本。)

  (參考學習鏈接:http://docs.oracle.com/javase/tutorial/java/IandI/override.html)  

  如果想要調用子類中有而父類中沒有的方法,需要進行強制類型轉換,如上面的例子中,將p轉換爲子類Child類型的引用。

  因爲當用父類的引用指向子類的對象,用父類引用調用方法時,找不到父類中不存在的方法。這時候需要進行向下的類型轉換,將父類引用轉換爲子類引用。     

 

結合實例說明               

  下面舉個例子(有問題的代碼已註釋):

  主要講講兩種類型轉換和兩種編譯時候的錯誤。  

多態示例代碼

  

  例子的執行結果:

  

  這段代碼:  

 

  Cat類中定義了eat()方法,但是Animal類中沒有這個方法,a1引用是Animal類的,所以找不到,編譯時出錯:

  

 

兩種類型的類型轉換

  (1)向上類型轉換(Upcast):將子類型轉換爲父類型。

  對於向上的類型轉換,不需要顯示指定,即不需要加上前面的小括號和父類類型名。

  

 

  (2)向下類型轉換(Downcast):將父類型轉換爲子類型。

  對於向下的類型轉換,必須要顯式指定,即必須要使用強制類型轉換

  

 

  並且父類型的引用必須指向子類的對象,即指向誰才能轉換成誰。

  不然也會編譯出錯:

 

 

  因爲父類引用指向的是Cat類的對象,而要強制轉換成Dog類,這是不可能的。

 



多態總結:其實我們生活中有很多地方也是用到多態的,比如生活的角色扮演,是兒子的話,看到爸爸應該叫爸爸,是學生看到老師,應該叫老師,我們在身份時時刻刻在進行不斷的變化,這就是多態。



多態注意:

成員的特點:

1,成員變量。

編譯時:參考引用型變量所屬的類中的是否有調用的成員變量,有,編譯通過,沒有,編譯失敗。

運行時:參考引用型變量所屬的類中的是否有調用的成員變量,並運行該所屬類中的成員變量。

簡單總結:編譯和運行都參考等號的左邊。哦了。

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

編譯時:參考引用型變量所屬的類中的是否有調用的函數。有,編譯通過,沒有,編譯失敗。

運行時:參考的是對象所屬的類中是否有調用的函數。

簡單總結:編譯看左邊,運行看右邊。因爲成員函數存在覆蓋特性。 

3,靜態函數。

編譯時:參考引用型變量所屬的類中的是否有調用的靜態方法。

運行時:參考引用型變量所屬的類中的是否有調用的靜態方法。

其實對於靜態方法,是不需要對象的。直接用類名調用即可。

簡單總結:編譯和運行都看左邊。

總結:非靜態成員函數,編譯時看左邊,運行時看右邊。其他都看左邊。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章