多態的好處:
A:提高了代碼的維護性(繼承保證)
B:提高了代碼的擴展性(由多態保證)
貓狗案例代碼
1 class Animal { 2 public void eat(){ 3 System.out.println("eat"); 4 } 5 6 public void sleep(){ 7 System.out.println("sleep"); 8 } 9 } 10 11 class Dog extends Animal { 12 public void eat(){ 13 System.out.println("狗吃肉"); 14 } 15 16 public void sleep(){ 17 System.out.println("狗站着睡覺"); 18 } 19 } 20 21 class Cat extends Animal { 22 public void eat() { 23 System.out.println("貓吃魚"); 24 } 25 26 public void sleep() { 27 System.out.println("貓趴着睡覺"); 28 } 29 } 30 31 class Pig extends Animal { 32 public void eat() { 33 System.out.println("豬吃白菜"); 34 } 35 36 public void sleep() { 37 System.out.println("豬側着睡"); 38 } 39 } 40 41 //針對動物操作的工具類 42 class AnimalTool { 43 private AnimalTool(){} 44 45 /* 46 //調用貓的功能 47 public static void useCat(Cat c) { 48 c.eat(); 49 c.sleep(); 50 } 51 52 //調用狗的功能 53 public static void useDog(Dog d) { 54 d.eat(); 55 d.sleep(); 56 } 57 58 //調用豬的功能 59 public static void usePig(Pig p) { 60 p.eat(); 61 p.sleep(); 62 } 63 */ 64 public static void useAnimal(Animal a) { 65 a.eat(); 66 a.sleep(); 67 } 68 //把所有的可能都歸為動物類 69 } 70 71 class DuoTaiDemo2 { 72 public static void main(String[] args) { 73 //我喜歡貓,就養了一只 74 Cat c = new Cat(); 75 c.eat(); 76 c.sleep(); 77 78 //我很喜歡貓,所以,又養了一只 79 Cat c2 = new Cat(); 80 c2.eat(); 81 c2.sleep(); 82 83 //我特別喜歡貓,又養了一只 84 Cat c3 = new Cat(); 85 c3.eat(); 86 c3.sleep(); 87 //... 88 System.out.println("--------------"); 89 //問題來了,我養了很多只貓,每次創建對象是可以接受的 90 //但是呢?調用方法,你不覺得很相似嗎?僅僅是對象名不一樣。 91 //我們准備用方法改進 92 //調用方式改進版本 93 //useCat(c); 94 //useCat(c2); 95 //useCat(c3); 96 97 //AnimalTool.useCat(c); 98 //AnimalTool.useCat(c2); 99 //AnimalTool.useCat(c3); 100 101 AnimalTool.useAnimal(c); 102 AnimalTool.useAnimal(c2); 103 AnimalTool.useAnimal(c3); 104 System.out.println("--------------"); 105 106 //我喜歡狗 107 Dog d = new Dog(); 108 Dog d2 = new Dog(); 109 Dog d3 = new Dog(); 110 //AnimalTool.useDog(d); 111 //AnimalTool.useDog(d2); 112 //AnimalTool.useDog(d3); 113 AnimalTool.useAnimal(d); 114 AnimalTool.useAnimal(d2); 115 AnimalTool.useAnimal(d3); 116 System.out.println("--------------"); 117 118 //我喜歡寵物豬 119 //定義一個豬類,它要繼承自動物,提供兩個方法,並且還得在工具類中添加該類方法調用 120 Pig p = new Pig(); 121 Pig p2 = new Pig(); 122 Pig p3 = new Pig(); 123 //AnimalTool.usePig(p); 124 //AnimalTool.usePig(p2); 125 //AnimalTool.usePig(p3); 126 AnimalTool.useAnimal(p); 127 AnimalTool.useAnimal(p2); 128 AnimalTool.useAnimal(p3); 129 System.out.println("--------------"); 130 131 //我喜歡寵物狼,老虎,豹子... 132 //定義對應的類,繼承自動物,提供對應的方法重寫,並在工具類添加方法調用 133 //前面幾個必須寫,我是沒有意見的 134 //但是,工具類每次都改,麻煩不 135 //我就想,你能不能不改了 136 //太簡單:把所有的動物都寫上。問題是名字是什么呢?到底哪些需要被加入呢? 137 //改用另一種解決方案。 138 139 } 140 141 /* 142 //調用貓的功能 143 public static void useCat(Cat c) { 144 c.eat(); 145 c.sleep(); 146 } 147 148 //調用狗的功能 149 public static void useDog(Dog d) { 150 d.eat(); 151 d.sleep(); 152 } 153 */ 154 }
2、
多態的弊端:
不能使用子類的特有功能。
我就想使用子類的特有功能?行不行?
行。
怎么用呢?
A:創建子類對象調用方法即可。(可以,但是很多時候不合理。而且,太占內存了)
B:把父類的引用強制轉換為子類的引用。(向下轉型)
對象間的轉型問題:
向上轉型:
Fu f = new Zi();
向下轉型:
Zi z = (Zi)f; //要求該f必須是能夠轉換為Zi的.(所屬關系)
多態的問題理解:
class 孔子爹 {
public int age = 40;
public void teach() {
System.out.println("講解JavaSE");
}
}
class 孔子 extends 孔子爹 {
public int age = 20;
public void teach() {
System.out.println("講解論語");
}
public void playGame() {
System.out.println("英雄聯盟");
}
}
//Java培訓特別火,很多人來請孔子爹去講課,這一天孔子爹被請走了
//但是還有人來請,就剩孔子在家,價格還挺高。孔子一想,我是不是可以考慮去呢?
//然后就穿上爹的衣服,帶上爹的眼睛,粘上爹的胡子。就開始裝爹
//向上轉型
孔子爹 k爹 = new 孔子();
//到人家那里去了
System.out.println(k爹.age); //40
k爹.teach(); //講解論語
//k爹.playGame(); //這是兒子才能做的
//講完了,下班回家了
//脫下爹的裝備,換上自己的裝備
//向下轉型
孔子 k = (孔子) k爹;
System.out.println(k.age); //20
k.teach(); //講解論語
k.playGame(); //英雄聯盟
2、向下轉型中有可能的異常:
ClassCastException:類型轉換異常
一般在多態的向下轉型中容易出現
