重載(overload):
對于類中的方法(包括從父類中繼承的方法),方法名相同,參數(shù)列表不同,就可以構(gòu)成重載關(guān)系液走。
參數(shù)列表不同,又可以分為參數(shù)類型、參數(shù)的個數(shù)贾陷、參數(shù)的順序缘眶。
重載與訪問權(quán)限修飾符和返回值無關(guān)。
覆蓋(override):
發(fā)生在子父類中,當父類中的某些方法不能滿足要求時,子類中改寫父類的方法,當父類的方法被覆蓋后,除非用super.方法名()來調(diào)用髓废。
發(fā)生覆蓋的條件:
1巷懈、三同一不低:
子類和父類的方法名,返回值類型和參數(shù)列表必須完全相同,而且子類方法的訪問修飾符的權(quán)限不能比父類低。(其實子類的方法返回值可以返回父類方法返回值的子類,當調(diào)用時會產(chǎn)生多態(tài)現(xiàn)象,當父類方法返回Number時,子類覆蓋的方法返回Integer類型)
2慌洪、被覆蓋的方法不能使final類型的,因為final修飾的方法無法被覆蓋顶燕。
3、被覆蓋的方法不能是private,否則在其子類中只是重新定義了一個方法,并沒有對其進行覆蓋,因為私有,子類看不到,談不上覆蓋冈爹。
4涌攻、子類不能比父類拋出更多的異常,即子類方法所拋出的異常必須和父類所拋出的異常一致或者是其子類,或什么都不拋出。
5频伤、被覆蓋的方法不能是static,如果父類中方法是靜態(tài),子類中是非靜態(tài)的,那么會發(fā)生編譯錯誤恳谎。原因:
即使父類和子類的方法都是靜態(tài)的,并滿足覆蓋條件,但仍不會發(fā)生覆蓋,因為靜態(tài)方法是在編譯的時候把靜態(tài)方法和類的引用類型進行匹配,可以理解成父類中的靜態(tài)方法和父類綁定在一起,在繼承的時候,子類中隱藏了父類的靜態(tài)方法,調(diào)用的時候Fu f = new Zi(); f.show()當調(diào)用靜態(tài)方法的時候,系統(tǒng)不在乎是哪個對象調(diào)用,而是直接看這個引用變量是什么類型的.
子類不會比父類拋出更多的異常,應該一樣或者比父類小,原因:
父類拋出A異常,當Fu類有子類的時候,根據(jù)多態(tài)可以寫成Fu f = new Zi(); 引用f指向子類對象,子類中把父類拋出的異常的方法進行覆蓋,但是由于子類繼承了父類,所以子類可以拋出異常的方法不能拋出新的異常,必須在父類拋出的異常范圍之內(nèi),另外 父類的方法調(diào)用者已經(jīng)做好了父類異常捕獲的準備,用多態(tài)調(diào)用時,卻出現(xiàn)捕獲之外的異常,jvm只能使程序終止.
關(guān)于非靜態(tài)內(nèi)部類中為什么不能有靜態(tài)成員(成員變量或方法)
非靜態(tài)內(nèi)部類依賴一個外部類的對象,對于外部類而言,非靜態(tài)內(nèi)部類只是一個成員,正常加載類時,先加載外部類-->創(chuàng)建外部類對象-->加載內(nèi)部類-->初始化變量,但是jvm要求所有靜態(tài)變量必須在對象創(chuàng)建之前完成加載,這就互相矛盾,對于非靜態(tài)內(nèi)部類而言,可以有static final int NUM = 3,原因:此時NUM屬于java常量,存放于內(nèi)存中的常量池中,加載常量和加載類的時機無關(guān).
多態(tài)下的成員變量和成員方法調(diào)用
Fu f = new Zi();
字段:
新創(chuàng)建的Zi類對象中有2個num字段
引用為父類型的引用,他調(diào)用自己的成員變量,相當于繼承的時候,父類的成員變量隱藏了(變量名想用,不管類型),簡單來說,引用類型是誰的,就調(diào)用誰的成員變量.
編譯運行都看左邊
成員方法:
成員方法調(diào)用實際上是堆內(nèi)存中的對象調(diào)用,但編譯的時候要現(xiàn)在引用所屬的類中檢查是否有這個方法,沒有就報錯(編譯器認為,Fu f調(diào)用的是父類中的方法),但運行時,盡管是f.show();Fu類型引用調(diào)用方法,但實際上是new Zi() 這個對象在調(diào)用,show()方法進行動態(tài)綁定在調(diào)用他的對象上,他會在子類中找有沒有show()方法,如果沒有就執(zhí)行父類繼承過來的方法.
編譯看左邊,運行看右邊
靜態(tài)方法:
對于靜態(tài)方法調(diào)用是不需要對象的,系統(tǒng)在加載的時候直接把靜態(tài)方法加載到數(shù)據(jù)共享區(qū),每個靜態(tài)方法都有自己的類所屬,靜態(tài)綁定,調(diào)用的時候直接看引用是什么類類型的就可以了
編譯運行都看左邊
靜態(tài)屬性,非靜態(tài)屬性,靜態(tài)方法都可以被繼承.然后會被隱藏,但是當子類中有沒重名的成員變量或者靜態(tài)方法,則調(diào)用父類的屬性或方法,如果子類有,那么就調(diào)用子類的
非靜態(tài)方法,調(diào)用就執(zhí)行多態(tài)
繼承時父類中有私有方法
因為private對類外面是不可見的,系統(tǒng)檢查的時候看不到,子類對象轉(zhuǎn)型為父類類型引用,檢查任務f.show()調(diào)用的是父類方法,父類中如果是私有就報錯(方法不可見),對于匿名對象調(diào)用方法,如果他所屬的類中方法是私有,就編譯失敗,如果說在子類中或父類中定義了私有方法,因為在同一類中可見,所以編譯通過,如果在父類中子類對象向上轉(zhuǎn)型,f.show()調(diào)用的仍然是父類的私有方法(此時說的情況是main方法在子父類中)