Java引用變量有兩個類型:編譯時類型和運行時類型。編譯時類型由聲明該變量時使用的類型決定,運行時類型由實際賦給該變量的對象決定。spa
若編譯時類型和運行時類型不一致,就出現多態code
正常的方法調用(本態調用)對象
Person e = new Person(); e.say(); Student e = new Student(); e.say;
虛擬方法調用(多態狀況下)blog
Person e = new Student(); e.say(); // 調用Student類的say()方法
編譯時類型和運行時類型編譯
編譯時e爲Person類型,而方法的調用是在運行時肯定的,因此調用的是Student類的say()方法。——動態綁定class
在虛擬方法調用狀況下,方法看重寫後的,但屬性沒有重寫一說,e.name爲Person中的name。變量
引用類型之間的類型轉換(對象的多態)cli
前提:父子關係語法
1、向上轉型引用
本質:父類的引用指向了子類的對象
語法:
父類類型 引用名 = new 子類類型();
特色:
編譯看左邊,運行看右邊
能夠調用父類類型中的全部成員,不能調用子類類型中特有成員;最終運行效果看子類的具體實現!
2、向下轉型
語法:
子類類型 引用名 = (子類類型)父類引用;
特色:
① 只能強轉父類的引用,不能強轉父類的對象
② 要求父類的引用必須指向的是當前目標類型的對象(已經指向子類類型的)
③ 能夠調用子類類型中全部的成員
示例:
public class TestPoly { public static void main(String[] args) { //子類——>父類 // 向上轉型(自動類型轉換):小——>大 Animal a =new Cat(); //能夠調用哪些成員 a.eat(); a.run(); a.age=10; a.name=""; a.method(); // a.climb(); // 向下轉型(強制類型轉換) Cat c = (Cat) a; // Cat c2 = (Cat)(new Animal()); // 報錯,必須是父類的引用 // Animal b = new Pig(); // Cat c3 = (Cat)b; // 可能不報錯,但實際應用內部不是Pig
//能夠調用哪些成員? c.run(); c.eat(); c.climb(); c.method(); c.name=""; c.age=1; c.color=""; } } class Animal{ String name; int age; public void eat(){ System.out.println("動物的吃"); } public void run(){ System.out.println("動物的跑"); } public void method(){ System.out.println("method"); } } class Pig extends Animal{ } class Cat extends Animal{ String color; public void run(){ System.out.println("貓飛快的跑"); } public void climb(){ System.out.println("貓爬樹"); } }
instanceof 判斷對象所屬類
x instanceof A:檢驗x是否爲類A的對象,返回值爲boolean型。
要求x所屬的類與類A必須是子類和父類的關係,不然編譯錯誤。
若是x屬於類A的子類B,x instanceof A值也爲true。
public class Person extends Object {…} public class Student extends Person {…} public class Graduate extends Person {…} ------------------------------------------------------------------- public void method1(Person e) { if (e instanceof Person) // 處理Person類及其子類對象 if (e instanceof Student) //處理Student類及其子類對象 if (e instanceof Graduate) //處理Graduate類及其子類對象 }