向上轉(zhuǎn)型
向上轉(zhuǎn)型:把對某個對象的引用視為對其基類型的引用的做法被稱作為向上轉(zhuǎn)型
后期綁定:在運行時根據(jù)對象的類型進行綁定苔巨,也叫作動態(tài)綁定或者運行時綁定勉抓;在Java中除了
static
和final
方法(private也屬于final方法)之外装蓬,其它所有的方法都是后期綁定灿渴;Java中所有的方法都可以通過后期綁定實現(xiàn)多態(tài)只有非
private
方法才可以被覆蓋(重寫)下梢,但是還是要密切注意覆蓋private方法的現(xiàn)象全肮,這時雖然編譯器不會報錯悬钳,但是也不會按照我們所期望的來執(zhí)行盐捷。確切的說柬脸,在導(dǎo)出類中,對于基類中的private方法毙驯,最好采用不同的名字
缺陷:域與靜態(tài)方法
-
任何域的訪問操作都將由編譯器解析倒堕,因此不是多態(tài)的
class Super{ public int field = 0; public int getField(){ return field; } } class Sub extends Super{ public int field = 1; public int getField(){ return field; } public int getSuperField(){ return super.field; } } public class FieldAccess{ public static void main(String[] args){ Super sup = new Sub(); System.out.println(sup.field); //0 System.out.println(sup.getField()); //1 Sub sub = new Sub(); System.out.println(sub.field); //1 System.out.println(sub.getField()); //1 System.out.println(sub.getSuperField()); //0 } }
-
如果某個方法時靜態(tài)的,它的行為就不具有多態(tài)性爆价;靜態(tài)方法是與類綁定垦巴,而并非與單個的對象相關(guān)聯(lián)的
class StaticSuper{ public static String staticGet(){ return "Base staticGet"; } public String dynamicGet(){ return "Base dynamicGet"; } } class StaticSub extends StaticSuper{ public static String staticGet(){ return "Derived staticGet"; } public String dynamicGet(){ return "Derived dynamicGet"; } } public class StaticMethod{ public static void main(String[] args){ StaticSuper sup = new StaticSub(); System.out.println(sup.staticGet()); //Base staticGet System.out.println(sup.dynamicGet()); //Derived dynamicGet } }
構(gòu)造器和多態(tài)
通常構(gòu)造器不同于其它種類方法,涉及到多態(tài)仍是如此铭段;盡管構(gòu)造器并不具有多態(tài)性(實際上是static方法骤宣,只不過static聲明是隱式的),但還是非常有必要理解構(gòu)造器怎樣通過多態(tài)在復(fù)雜的層次結(jié)構(gòu)中運作
基類的構(gòu)造器總是在導(dǎo)出類的構(gòu)造過程中被調(diào)用序愚,而且按照繼承層次逐漸向上鏈接憔披,以使每個基類的構(gòu)造器都能得到調(diào)用
復(fù)雜對象調(diào)用構(gòu)造器的順序:
調(diào)用基類的構(gòu)造器
,按照聲明順序調(diào)用成員的初始化方法
爸吮,調(diào)用導(dǎo)出類構(gòu)造器的主體
-
在構(gòu)造器內(nèi)唯一能夠安全調(diào)用的那些方法是基類中的
final
方法或private
方法芬膝,這些方法不能被覆蓋,不會出現(xiàn)在父類中調(diào)用子類重寫的方法形娇,而此時子類還沒有初始化的問題class Glyph{ void draw(){ System.out.println("Glyph.draw()"); } Glyph(){ System.out.println("Glyph() before draw()"); draw(); System.out.println("Glyph() after draw()"); } } class RoundGlyph extends Glyph{ private int radius = 1; RoundGlyph(int r){ radius = r; System.out.println("RoundGlyph.RoundGlyph(), radius = "+radius); } void draw(){ System.out.println("RoundGlyph.draw(), radius = "+radius) } } public class PolyConstructors{ public static void main(String[] args){ new RoundGlyph(5); //Glyph() before draw() //RoundGlyph.draw(), radius = 0 //Glyph() after draw() //RoundGlyph.RoundGlyph(), radius = 5 } }