1. 程式人生 > >Java面向物件四大特性

Java面向物件四大特性

1.多型 :晚繫結,執行時,一個介面,多種實現

  1. 面向物件的四大特性:封裝、繼承、多型、抽象。從一定角度來看,封裝和繼承幾乎都是為多型而準備的。是最重要的知識點。
  2. 多型的定義指允許不同類的物件對同一訊息做出響應。即同一訊息可以根據傳送物件的不同而採用多種不同的行為方式。(傳送訊息就是函式呼叫)
  3. 實現多型的技術稱為:動態繫結(dynamic binding),是指在執行期間判斷所引用物件的實際型別,根據其實際的型別呼叫其相應的方法。
  4. 多型的作用消除型別之間的耦合關係
  5. 現實中,關於多型的例子不勝列舉。比方說按下 F1 鍵這個動作,如果當前在 Flash 介面下彈出的就是 AS 3 的幫助文件;如果當前在 Word 下彈出的就是 Word 幫助;在 Windows 下彈出的就是 Windows 幫助和支援。同一個事件發生在不同的物件上會產生不同的結果。(from  http://www.cnblogs.com/jack204/archive/2012/10/29/2745150.html)

下面是多型存在的三個必要條件,要求大家做夢時都能背出來!

多型存在的三個必要條件
一、要有繼承;
二、要有重寫;
三、父類引用指向子類物件

 多型的好處

1.可替換性(substitutability)。多型對已存在程式碼具有可替換性。例如,多型對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
2.可擴充性(extensibility)。多型對程式碼具有可擴充性。增加新的子類不影響已存在類的多型性、繼承性,以及其他特性的執行和操作。實際上新加子類更容易獲得多型功能。例如,在實現了圓錐、半圓錐以及半球體的多型基礎上,很容易增添球體類的多型性。
3.介面性(interface-ability)。

多型是超類通過方法簽名,向子類提供了一個共同介面,由子類來完善或者覆蓋它而實現的。如圖8.3 所示。圖中超類Shape規定了兩個實現多型的介面方法,computeArea()以及computeVolume()。子類,如Circle和Sphere為了實現多型,完善或者覆蓋這兩個介面方法。
4.靈活性(flexibility)。它在應用中體現了靈活多樣的操作,提高了使用效率。
5.簡化性(simplicity)。多型簡化對應用軟體的程式碼編寫和修改過程,尤其在處理大量物件的運算和操作時,這個特點尤為突出和重要。


Java中多型的實現方式:介面實現,繼承父類進行方法重寫,同一個類中進行方法過載。

例項:

[java]  view plain  copy
  1. public class Wine {  
  2.     public void fun1(){  
  3.         System.out.println("Wine 的Fun.....");  
  4.         fun2();  
  5.     }  
  6.       
  7.     public void fun2(){  
  8.         System.out.println("Wine 的Fun2...");  
  9.     }  
  10. }  
  11.   
  12.   
  13. public class JNC extends Wine{  
  14.     /** 
  15.      * @desc 子類過載父類方法 
  16.      *        父類中不存在該方法,向上轉型後,父類是不能引用該方法的 
  17.      * @param a 
  18.      * @return void 
  19.      */  
  20.     public void fun1(String a){  
  21.         System.out.println("JNC 的 Fun1...");  
  22.         fun2();  
  23.     }  
  24.       
  25.     /** 
  26.      * 子類重寫父類方法 
  27.      * 指向子類的父類引用呼叫fun2時,必定是呼叫該方法 
  28.      */  
  29.     public void fun2(){  
  30.         System.out.println("JNC 的Fun2...");  
  31.     }  
  32. }  
  33.   
  34.   
  35. public class Test {  
  36.     public static void main(String[] args) {  
  37.         Wine a = new JNC();  
  38.         a.fun1();  
  39.     }  
  40. }  
  41. -------------------------------------------------  
  42. Output:  
  43. Wine 的Fun.....  
  44. JNC 的Fun2...  

 例2: 多型==晚繫結

  不要把函式過載理解為多型。

  因為多型是一種執行期的行為,不是編譯期的行為。

  多型:父型別的引用可以指向子型別的物件。

  比如 Parent p = new Child();

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

    如果有,再去呼叫子類的該同名方法

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

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

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

  因為當用父類的引用指向子類的物件,用父類引用呼叫方法時,找不到父類中不存在的方法。這時候需要進行向下的型別轉換,將父類引用轉換為子類引用。     

結合例項說明               

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

[java]  view plain  copy
  1. public class PolyTest  
  2. {  
  3.     public static void main(String[] args)  
  4.     {  
  5.           
  6.         //向上型別轉換  
  7.         Cat cat = new Cat();  
  8.         Animal animal = cat;  
  9.         animal.sing();  
  10.   
  11.                   
  12.         //向下型別轉換  
  13.         Animal a = new Cat();  
  14.         Cat c = (Cat)a;  
  15.         c.sing();  
  16.         c.eat();  
  17.   
  18.   
  19.         //編譯錯誤  
  20.         //用父類引用呼叫父類不存在的方法  
  21.         //Animal a1 = new Cat();  
  22.         //a1.eat();  
  23.           
  24.         //編譯錯誤  
  25.         //向下型別轉換時只能轉向指向的物件型別          
  26.         //Animal a2 = new Cat();  
  27.         //Cat c2 = (Dog)a2;  
  28.           
  29.   
  30.   
  31.     }  
  32. }  
  33. class Animal  
  34. {  
  35.     public void sing()  
  36.     {  
  37.         System.out.println("Animal is singing!");  
  38.     }  
  39. }  
  40. class Dog extends Animal  
  41. {  
  42.     public void sing()  
  43.     {  
  44.         System.out.println("Dog is singing!");  
  45.     }  
  46. }  
  47. class Cat extends Animal  
  48. {  
  49.     public void sing()  
  50.     {  
  51.         System.out.println("Cat is singing!");  
  52.     }  
  53.     public void eat()  
  54.     {  
  55.         System.out.println("Cat is eating!");  
  56.     }  
  57. }  


  例子的執行結果:

  

  這段程式碼:  

 

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

  

 

兩種型別的型別轉換

  (1)向上型別轉換(Upcast):將子型別轉換為父型別。

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

  

 

  (2)向下型別轉換(Downcast):將父型別轉換為子型別。

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

  

 

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

  不然也會編譯出錯:

 

 

  因為父類引用指向的是Cat類的物件,而要強制轉換成Dog類,這是不可能的

2.抽象

     對於面向物件程式設計來說,抽象是它的一大特徵之一。在Java中,可以通過兩種形式來體現OOP的抽象:介面和抽象類。這兩者有太多相似的地方,又有太多不同的地方。很多人在初學的時候會以為它們可以隨意互換使用,但是實際則不然。今天我們就一起來學習一下Java中的介面和抽象類。下面是本文的目錄大綱:

  一.抽象類

  二.介面

  三.抽象類和介面的區別

  若有不正之處,請多多諒解並歡迎批評指正,不甚感激。

  請尊重作者勞動成果,轉載請標明原文連結:

  http://www.cnblogs.com/dolphin0520/p/3811437.html

一.抽象類

  在瞭解抽象類之前,先來了解一下抽象方法。抽象方法是一種特殊的方法:它只有宣告,而沒有具體的實現