從對(duì)象的內(nèi)存角度來理解試試. 假設(shè)現(xiàn)在有一個(gè)父類Father,它里面的變量需要占用1M內(nèi)存.有一個(gè)它的子類Son,它里面的變量需要占用0.5M內(nèi)存. 現(xiàn)在通過代碼來看看內(nèi)存的分配情況: Father f = new Father();//系統(tǒng)將分配1M內(nèi)存. Son s = new Son();//系統(tǒng)將分配1.5M內(nèi)存!因?yàn)?span>子類中有一個(gè)隱藏的引用super會(huì)指向父類實(shí)例,所以在實(shí)例化子類之前會(huì)先實(shí)例化一個(gè)父類,也就是說會(huì)先執(zhí)行父類的構(gòu)造函數(shù).由于s中包含了父類的實(shí)例,所以s可以調(diào)用父類的方法. Son s1 = s;//s1指向那1.5M的內(nèi)存. Father f1 = (Father)s; 相當(dāng)于Father f1 = new Son(); 為向上類型轉(zhuǎn)換,,可省略,,因?yàn)樽宇惥褪歉割悾缲埦褪莿?dòng)物 //這時(shí)f1會(huì)指向那1.5M內(nèi)存中的1M內(nèi)存,即是說,f1只是指向了s中實(shí)例的父類實(shí)例對(duì)象,所以f1只能調(diào)用父類的方法(存儲(chǔ)在1M內(nèi)存中),而不能調(diào)用子類的方法(存儲(chǔ)在0.5M內(nèi)存中). Son s2 = (Son)f; //Error 不可直接向下類型轉(zhuǎn)換 //這句代碼運(yùn)行時(shí)會(huì)報(bào)ClassCastException.因?yàn)?span>f中只有1M內(nèi)存,而子類的引用都必須要有1.5M的內(nèi)存,所以無法轉(zhuǎn)換. Son s3 = (Son)f1; 強(qiáng)制類型轉(zhuǎn)換,,為向下類型轉(zhuǎn)換,,前提是父類引用要先指向子類對(duì)象 //這句可以通過運(yùn)行,這時(shí)s3指向那1.5M的內(nèi)存.由于f1是由s轉(zhuǎn)換過來的,所以它是有1.5M的內(nèi)存的,只是它指向的只有1M內(nèi)存. 示例: 1 .如果你想實(shí)現(xiàn)多態(tài),那么必須有三個(gè)條件,父類引用,子類對(duì)象,方法覆蓋你這里如果Fathor類有一個(gè)show()方法,那么形成方法覆蓋,那么此時(shí)就可以這么寫:obj.show(),此刻形成了多態(tài). 2. 沒有方法覆蓋,那你這里只能解釋為父類引用去訪問一個(gè)子類的方法,當(dāng)然,父類引用沒有這么大范圍的權(quán)限,當(dāng)然會(huì)報(bào)錯(cuò) PS:多態(tài)實(shí)際上是一種機(jī)制,在編譯時(shí)刻,會(huì)生成一張?zhí)摂M表,來記錄所有覆蓋的方法,沒有被覆蓋的方法是不會(huì)記錄到這張表的.若一個(gè)父類引用調(diào)用了沒有覆蓋的子類方法,那么是不符合該表的,那么編譯時(shí)刻就會(huì)報(bào)錯(cuò). 在執(zhí)行程序的時(shí)候,虛擬機(jī)會(huì)去這張?zhí)摂M表中找覆蓋的方法,比如引用中實(shí)際上存的是一個(gè)子類對(duì)象引用,那么就會(huì)去找子類中的相應(yīng)的覆蓋的方法來執(zhí)行
定義一個(gè)父類類型的引用指向一個(gè)子類的對(duì)象既可以使用子類強(qiáng)大的功能,,又可以抽取父類的共性,。
變量是不存在重寫覆蓋的,!
類中的屬性是沒有多態(tài)性的,,即你在引用上面使用屬性時(shí),系統(tǒng)只會(huì)去找引用的靜態(tài)類型中的那個(gè)屬性,,而與它的實(shí)際類型無關(guān),。 |
|