一、多態:事物的多種狀態,polymorphic網絡
對象的多態性:同一個對象,可能具備不一樣的名稱,同一個對象,有不一樣的類型的引用指向它。
本質:同一個物體有不一樣的名稱和描述。 狗 :狗 動物
類型的多態性:同一個類型,可能具備不一樣的子類實現,同一個類型引用,有不一樣的對象實現,
本質:同一個名字和描述,能夠在不一樣場景下有不一樣的真實實現。
動物: 狗 貓 豬ide
二、多態的前提spa
子類繼承父類 方法的重寫 父類的引用指向子類的對象code
class Test { public static void main(String[] args) { Person p = new P1();//父類的引用指向子類的對象 p.run(); } } class Person { public void run(){ System.out.println("走走走"); } } class P1 extends Person //繼承 { public void run(){//方法的重寫 System.out.println("跑起來"); } }
三、多態中成員變量的訪問特色對象
編譯看左邊,運行看左邊(編譯時看父類是否有該變量的定義,運行時獲取到的是父類的結果)blog
在子類對象中有一塊區域是super區域,存放繼承父類的變量和方法,容易理解,變量a的類型是Fu類型,繼承
所以a.age能夠看作是supper.age,因此輸出就是Fu.age變量。編譯
四、多態中成員方法的訪問特色event
編譯看左邊,運行看右邊(編譯時看父類是否認義該方法,運行時運行子類重寫的方法)class
動態綁定
在JVM執行到方法時,會根據這個方法所屬變量類型標識符找到該方法的全限定名(包名+類名),
這裏所屬變量類型是父類,可是隻知道所屬變量類型還不可以的,由於沒法肯定方法的具體位置(非靜態
方法確定是在堆中),就沒法壓到棧中執行,所以必須根據父類變量建立的實際對象肯定方法的具體位置
(在堆中尋找),這種在程序執行過程當中,經過動態建立的方法表來定位方法的方式,稱爲動態綁定。
五、多態中靜態方法的訪問特色
編譯看左邊,運行看左邊(編譯時看父類是否認義該方法,運行時運行父類的方法)
緣由:方法屬於類,和父類的方法不屬於重寫關係
靜態變量:存儲在類的字節碼中的變量,被全部對象所共享,不隨着對象的變化而變化,
都有相同的值,因此稱爲靜態變量
靜態方法:只會根據引用所屬的父類,來決定運行的內容,運行內容,不會隨着子類的變化而變化,
都是引用所屬的父類的方法實現,因此稱爲靜態方法。
public class Test { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.age); f.run(); f.show(); } } class Fu{ int age=10; public void run() { System.out.println("run run run"); } public static void show() { System.out.println("show show show"); } } class Zi extends Fu{ int age=5; public void run() { System.out.println("go go go"); } public static void show() { System.out.println("show time"); } }
六、向上向下轉型
當想要訪問子類中的屬性或子類特有的方法時,須要向下轉型
這裏有一個instanceof方法,能夠進行一次判斷
格式:子類類型 引用名稱 = (子類類型)父類類型的引用;
eg: Zi z = (Zi)f;
本質:恢復子類本來的訪問範圍
七、多態的好處
一、提升了代碼的可擴展性
二、在方法的參數列表中,能夠定義父類類型的引用,未來調用的時候,全部的子類類型的對象,
均可以做爲方法的實際參數。
三、不在方法的參數列表中,就在普通的方法體中,使用父類的類型指向子類的對象,
也能提升代碼的可擴展性。對象的來源很是普遍,不只僅是new出來的,(還多是經過反射獲取的,
經過文件讀取的,還多是網絡傳遞的,在寫代碼的編譯階段,沒法知道對象具體的子類類型的)
須要使用父類類型的引用,操做不知道的子類類型的對象。