Java類的繼承
繼承的語法結構:
[修飾符列表] class 子類名 extends 父類名{
類體;
}
子類就是當前這個類,父類就是我們要復用的那個類
java中只支持單繼承;c++支持多繼承
一個類如果沒有顯式繼承其他類,則該類默認繼承Object
任何一個類都有一個始祖類Object,所有類的超類。
為什么要繼承?
代碼的復用,方法的重寫、覆蓋。
在有繼承關系的兩個類中:
private(私有)可以被繼承,但無法訪問和覆蓋,即使在子類中覆蓋了父類的方法,在多態里面仍然會調用父類的方法。
靜態方法有繼承無覆蓋,覆蓋發生在對象的成員方法中,也就是發生在堆內存中,但是靜態數據都是在靜態內存塊中。
發生覆蓋的條件:
1 發生在有繼承關系的兩個類之間
2 方法必須具有相同的方法名,返回值類型,參數列表(如果參數列表不同,系統會默認這兩個重載后的不同的兩個方法)
3 重寫的方法不能比被重寫的方法有更低的訪問權限
4 重寫的方法不能比被重寫的方法拋出更寬泛的異常
5 私有方法不能被覆蓋,不調用不報錯,調用就報錯
6 構造方法無法被覆蓋,因為構造方法不能被繼承
7 靜態方法不存在覆蓋,繼承是對象的繼承,而不是類的繼承。靜態方法進入內存以后,不會再有新的內存變化,所以沒有覆蓋這一說。
8 覆蓋指的是成員方法,和成員變量無關。
public class Extends_01{ public static void main(String[] args){ SubClass.eat(); SubClass sb = new SubClass(); sb.sing("愛你一萬年"); System.out.println( SubClass.name ); } }
public class SubClass extends SuperClass{ }
public class SuperClass{ static String name = "劉德華"; int age; public static void eat(){ System.out.println( "這個是父類SuperClass的eat()方法" ); } public void sing(String sname){ System.out.println( "我喜歡唱歌,你點----這個是父類SuperClass的sing()方法" + sname ); } }
輸出結果:
可以看到在SubClass類中是沒有任何方法或變量的,它所有的屬性都來自父類,在main調用SubClass方法,調用的是SubClass從父類繼承過來的。
多態:
多態發生在賦值時
多態只跟成員方法有關
在這里先說明一下動態綁定和靜態綁定。
靜態綁定:
編譯時(javac的時候)就把數據賦值,叫靜態綁定。把我們寫的源代碼編譯成對應的機器碼,檢查語法錯誤,拼寫檢查。
綁定:把引用數據類型直接綁定類型明確,就是把賦值運算符前后的類型指定死,並且聲明說不能更改,這個時候叫靜態綁定。
這個時候的賦值是指給類對象中的成員變量賦值。
動態綁定:
程序運行的時候,我們程序的行為,特別是內存行為,可以按照需求改變,這種就叫動態綁定。這種改變對應到代碼上就是不同的對象行為,不同的對象,對應的是不同代碼,不同的代碼對應又是不同的內存操作,不同的代碼會有不同的名字。
多態的定義:父類的引用指向子類的對象。
父類的引用:一是指父類變量指向的那個內存空間
二也是指父類自由的類型信息表,這個表示任何對象都具備的,和繼承多態無關。
子類的對象:
一是指子類的那個堆內存空間。
二也是指子類的那個類型信息表。
多態(向上轉型)就是用父類對象的類型信息表去調用子類類型信息表中和父類相同的成員方法。所謂相同,就是之前子類覆寫父類方法。父類信息表中沒有的成員方法,就調用不到.
這里還有一個轉型是向下轉型,就是用子類的類型信息表代替父類的類型信息表,就可以完全的讓位子類對象中所有的變量和方法。
為了避免java.lang.ClassCastException錯誤,需要一個關鍵字instanceof判斷
if(引用 instanceof 類型名)