江湖上傳聞,面向對象之因此厲害,是由於它擁有封裝、繼承與多態三項神技,只要三板斧一出,號令天下誰敢不從。前面費了老大的勁纔講清楚封裝和繼承,那麼多態又是怎樣的神乎其神呢?下面先經過一個簡單的例子來講明多態的使用場景。
首先把雞這種家禽經過面向對象來表達,方便起見只定義兩個屬性(名稱和性別),以及一個call方法,定義好的雞類代碼以下所示:html
//定義一個雞類 public class Chicken { // 定義一個名稱屬性 public String name; // 定義一個性別屬性 public int sex; // 定義一個叫喚方法 public void call() { System.out.println("半夜雞叫"); } }
接着從上面的Chicken類派生出公雞類Cock,將公雞的性別固定設置爲雄性,同時重寫call這個叫喚方法。公雞類的代碼示例以下:java
//定義一個繼承自雞類的公雞類 public class Cock extends Chicken { public Cock() { // 公雞的性別固定爲雄性 sex = 0; } // 重寫了公雞的叫喚方法 public void call() { System.out.println("喔喔喔"); } }
一樣編寫母雞類Hen繼承自Chicken類,將母雞的性別固定設置爲雌性,同時重寫call這個叫喚方法。母雞類的代碼示例以下:測試
//定義一個繼承自雞類的母雞類 public class Hen extends Chicken { public Hen() { // 母雞的性別固定爲雌性 sex = 1; } // 重寫了母雞的叫喚方法 public void call() { System.out.println("咯咯咯"); } }
最後在外部建立一個Chicken雞類的實例,先將公雞實例賦值給這個雞類實例chicken,緊接着調用chicken的call方法;再將母雞實例賦值給雞類實例chicken,緊接着調用chicken的call方法。按此步驟編寫的測試調用代碼見下:日誌
//演示類的多態性 public class TestChicken { public static void main(String[] args) { // 雞類的實例變成了一隻公雞 Chicken chicken = new Cock(); // 此時雞類的叫聲就變爲公雞的叫聲 chicken.call(); // 雞類的實例變成了一隻母雞 chicken = new Hen(); // 此時雞類的叫聲就變爲母雞的叫聲 chicken.call(); } }
運行以上的測試代碼,觀察到如下的日誌信息:htm
喔喔喔 咯咯咯
由日誌結果可見,儘管chicken原本是雞類的實例,然而兩次調用chicken的call方法,卻沒有輸出雞類的叫聲,而是前後打印了公雞類的叫聲和母雞類的叫聲。這個現象即是多態特性的一個實際運用,所謂多態,意思是有多種狀態,比如古人的卸甲歸田,穿上盔甲去打仗就是士兵,卸下盔甲去種田就是農民。多態的實現依賴於繼承,先聲明一個父類的實例,再於合適之時給它分別賦予不一樣的子類實例,此後操做該實例就彷彿操做子類的實例通常。
引入多態概念的好處是,只要某些類型都從同一個父類派生而來,就能在方法內部把它們看成同一種類型來處理,而無需區分具體的類型。仍以雞叫爲例,無論是公雞叫仍是母雞叫,都是某種雞在叫,因而徹底能夠定義一個叫喚方法,根據輸入的雞參數,讓這隻雞本身去叫便可。叫喚方法的具體代碼以下所示:對象
// 定義一個叫喚方法,傳入什麼雞,就讓什麼雞叫 private static void call(Chicken chicken) { chicken.call(); }
這下有了通用的雞叫方法,外部就能把雞類的實例做爲輸入參數填進去。當輸入參數爲公雞實例的時候,call方法上演的是公雞喔喔叫;當輸入參數爲母雞實例的時候,call方法上演的是母雞咯咯叫。blog
call(new Cock()); // 公雞叫 call(new Hen()); // 母雞叫
更多Java技術文章參見《Java開發筆記(序)章節目錄》繼承