五(十)、多型
多型性:一個事物的多種形態;
1.何為多型性?
物件的多型性,父類的引用指向子類物件;換句話就是說:向上轉型;看例子;
1 public class Day12Polymorphism17 { 2 3 public static void main(String[] args) { 4 Persons4 person = new Persons4(); 5 //person.eat(); 6 7 Man man = new Man(); 8 //man.eat(); 9 man.age = 25;10 //man.earnMony(); 11 //物件的多型性,父類的引用指向子類的物件; 12 Persons4 p1 = new Man(); 13 Persons4 p2 = new Woman(); 14 p1.eat(); 15 p1.walk(); 16 //p1.earnMony();只能掉用父類方法,執行的是子類發方法;由於變數宣告為父類型別,導致編譯時,只能呼叫父類宣告的屬性,子類的屬性和方法不能呼叫 17 p2.eat(); 18 System.out.println(p1.id);19 20 } 21 }
這裡Persons4 是父類,Man是子類,Persons4 p1 = new Man(); 也就是向上轉型;new Man()為子類物件;p1是引用;所以就是 父類的引用指向子類物件;
附上相關程式碼:
1 class Persons4{ 2 String name; 3 int age; 4 int id = 1001;//身份證號 5 6 public Persons4() { 7 } 8 public Persons4(String name, int age) {9 this.name = name; 10 this.age = age; 11 } 12 13 public void eat() { 14 System.out.println("吃飯"); 15 } 16 public void walk() { 17 System.out.println("走了"); 18 } 19 } 20 21 class Man extends Persons4{ 22 boolean isSmoking; 23 int id = 1002;//身份證號 24 public void earnMony() { 25 System.out.println("男人負責掙錢養家"); 26 } 27 public void eat() { 28 System.out.println("男人多吃飯"); 29 } 30 } 31 32 class Woman extends Persons4{ 33 boolean isBeauty; 34 public void goShopping(){ 35 System.out.println("女人,喜歡購物"); 36 } 37 public void eat() { 38 System.out.println("女人吃的少"); 39 }
當呼叫子父類同名同參數的方法時,實際執行的是子類重寫父類的方法;虛擬方法呼叫;也就是說 p1.eat(); 結果是:男人多吃飯 p1.walk()結果是:“走了”
2.多型的使用:虛擬方法呼叫
有了物件的多型性以後,我們只能在編譯器,只能呼叫父類中宣告的方法,但是在執行期,我們實際執行的是子類重寫的父類的方法;
總結:方法:編譯看左邊,執行看右邊;
屬性 編譯和執行都看左邊;
4.多型的使用前提:
a.要有類的繼承關係;
b.要有方法的重寫;
5.物件的多型性只適用於方法,不適合用屬性;
p1.id 這裡的結構還是1001
6.多型是執行時方法;
這裡,多型的使用時為了讓程式碼更加簡潔,讓引數統一化;比如在方法的引數可以接受父類引數,那麼如果你傳入子類也可以,就可以簡化程式碼了。那麼這裡就會又引入另外一個問題,如果方法引數是父類形參,當傳入子類引數時,處理這個形參時,如何把 父類轉換為子類物件呢?這樣就引入了向下轉型;向下轉型符號 即強制型別轉換符 “()”;
1 public static void main(String[] args) { 2 Persons4 person = new Persons4(); 3 Persons4 p1 = new Man();//多型 4 Man man = (Man)p1;//向下型別轉換 使用強制型別轉換,可能異常; 14 if(p1 instanceof Woman) { 15 System.out.println("是女人,不可以強轉"); 16 }else if(p1 instanceof Man) { 17 System.out.println("是男人,可以強轉"); 18 } 19 //相關問題; 20 //編譯過,執行不過; 21 Persons5 p2 = new Woman1(); 22 Man1 m2 = (Man1)p2; 23 24 Persons5 p3 = new Persons5(); 25 Man1 m3 = (Man1)p3; 26 27 //編譯過,執行也過 28 Object obj = new Woman1(); 29 Persons5 p4 = (Persons5) obj; 30 31 //編譯不通過 32 //Man1 m5 = new Woman1(); 33 34 }
instanceof 關鍵字的使用說明:
a instanceof A:判斷物件a是否是類A的例項,如果是,返回true,否則false;
B 是 A 的父類,如果 a instanceof A: 返回true,b instanceof A:返回也是true;
為了避免出現classcaseException的異常,我們在向下轉型之前,先進行instanceof的判斷,