標籤:java基礎
執行流程
1:Animal a = new Cat();1.1:在棧中建立地區,類型為Animal,變數名:a;1.2:在堆中new Cat();佔用一塊地區。地址值:[0x3a4]1.3:spuer()執行個體化父類Animal。1.3.1:new Animal();佔用一塊地區,地址值:0x3ab;1.3.2:引用著在方法區中初始化[Animal中的所有方法,該引用為:[0x754]]。1.3.3:將Animal()引用賦給spuer();spuer引用著Animal();1.4:在方法區中初始化Cat類的所有方法,引用值為0x343。1.5:將0x3a4賦給棧中的變數a;a就開始引用Cat()。2:a.eat();2.1:通過[0x3a4]找到Cat。2.2:編譯時間期:先spuer()找到Animal中的方法。如果沒有,則報錯。2.3:運行時:直接在Cat中找到eat(),當Cat中沒有,再去Animal中找。2.4:將eat()方法要方法區壓棧,執行,輸出:SOP(貓吃魚);3:a = new Dog();3.1:在堆new Dog(),開闢一塊新地區,地址值:0x87xfds3.2:spuer();執行個體化父類Animal 3.2.1:new Animal()開闢新地區,地址值0x33fa;3.2.2:成員方法引用著方法區中已初始化的[0x754];3.2.3:將Animal地址值0x33fa賦給spuer();;spuer引用著Animal();3.3:在方法區中初始化Dog類的所有方法,引用值為0x422ac。3.4:將[0x87xfds]賦給棧中的變數a; a不再引用Cat,而是引用著Dog;這時堆中的Cat已成為垃圾,等待JVM空閑時來回收。4:a.eat();4.1:通過a變數引用值找到堆中標記為0x87xfds的地區。4.2:編譯時間:先進super();去檢查Animal引用的方法區中有沒有eat()方法,如有沒有則報錯。4.3:運行時:直接去Doa方法區中找到eat();如果Doa沒有,再去執行super()調用父類的eat()方法。4.4:從方法區中將eat()壓棧,執行(SOP('狗吃糧'))。5:a.shudy();5.1:通過a變數引用值找到堆中標記為0x87xfds的地區。5.2:編譯時間:先進super();去檢查Animal引用的方法區中有沒有shudy()方法,結果Animal中沒有shudy()方法,所以就在編譯時間期就報錯。6:Dog d = (Dog)a;6.1:在棧中開闢地區,儲存類型為Dog,變數名d6.2:將a向下轉型,從Animal轉為Dog來引用Dog;(將a變數賦給d)6.3:a和d都指向堆中同一個Dog對象。7:d.eat();//從Dog方法中壓棧執行eat()方法,然後彈棧;8:d.shudy();//從Dog方法中壓棧執行shudy()方法,然後彈棧;9:Cat c = (Cat) a;9.1:在棧中開闢一塊地區,儲存類型:Cat,變數名稱:c9.2:將a向下轉型,將Anmail引用Dao轉為Cat引用Dog;結果拋出類型轉換異常。Dog不能被轉為Cat;
總結: 1:多態=繼承+重寫+父類引用子類 如: Fu ff = new Zi(); 2:普通成員 變數:都參考左邊,因為變數不存在重寫,方法中調用變數採用就近原則。 方法:編譯參考左邊,運行參考右邊。 3:靜態成員 變數和方法:編譯運行都參考左邊; 因為靜態與對象無關。成員加靜態修飾的沒加private,都可以被類直接調用,所以參考的都是左邊。