繼承是面向?qū)ο缶幊痰娜筇卣髦唬彩菍崿F(xiàn)代碼復(fù)用的重要手段。java中繼承具有單繼承的特點,每一個類只可以直接繼承一個父類,即直接父類,不可以同時繼承多個類。但是繼承是可以多層繼承的,即:父類還有父類,頂級的父類為Object類。也就是說,任何類都是Object的子類,Object是任何類的父類。
如果編寫的類沒有直接繼承其他類,默認繼承的是Object類
子類 了父類的一些特征。子輩從父輩那里可以繼承一筆財富稱為繼承,子類從父類那里可以繼承一些代碼稱為繼承。
以已有的類作為父類(基類),從這個父類已有的功能和屬性上,在新的類(子類)中,添加其他方法和屬性,達到復(fù)用代碼的目的,而不用再編寫父類已存在的代碼,這樣就達到了代碼的復(fù)用!
提示:
當(dāng)我們描述一類事物時候,發(fā)現(xiàn)這些事物具備相同的屬性,我們將這些共性屬性進行抽取,用單獨的類來描述共同的屬性,讓這類事物繼承抽取出來的類描述的對象,實現(xiàn)的代碼的復(fù)用。但是請注意,繼承是一類事物共性的向上抽取,所以不能單純的為了簡寫代碼而使用繼承。
JavaJDK中提供了大量的類,這些類通過一層一層的繼承,形成一個龐大的繼承樹,最頂級為Object類,一定要注意,這個繼承樹的形成是N多個類的共性的抽取,一層一層抽取共性,直至抽取到Object類,而不是說:所有功能的類都是通過Object派生出去的!
//描述貓的時候,繼承狗,雖然也具備了name屬性,但是意義完全錯誤。
class Cat extends Dog
{
String id;
}
如果在描述對象時,只是為了簡寫代碼,不可以使用繼承的特性定義了一些和描述對象完全不相關(guān)的成員。
如果只是為了簡寫代碼的編寫,完全可以將這些不相關(guān)的代碼編寫一個單獨的工具類來實現(xiàn)。
class Dog { Stringname; Stringage; voidmethod1(){ System.out.PRintln("今天星期一"); } voidmethod2(){ System.out.println("天氣晴"); } voidmethod3(){ System.out.println("今天沒霧霾"); }} class DaoMang extends Dog{ /*在這里編寫代碼時候,需要用到父類的方法,可以 直接調(diào)用,編寫代碼確實很爽,但是這和繼承思想 完全沒有任何關(guān)系!因為執(zhí)行父類的那些方法和描述 對象沒有任何關(guān)系!!*/ voidmethod(){ method1(); } }編寫dog繼承類代碼。class Dog { Stringname; Stringage; voidworking(){ System.out.println("看家!"); }} class DaoMang extends Dog{ String id;}特點:
java繼承通過使用extends關(guān)鍵字來實現(xiàn),實現(xiàn)繼承的類被稱為子類,被繼承類稱為父類。例如:動物是狗的父類,狗是哈士奇的父類。
定義格式:
修飾符 class 子類 extends 父類{
}
重寫:Override:
子類繼承父類后,在原有的基礎(chǔ)上可以進行擴展,如新增屬性、方法,但是有一種情況,例如:狗類具有工作方法搜救犬的工作是搜救,導(dǎo)盲犬的功能是導(dǎo)盲,那這個時候他們的工作方法內(nèi)容就不一樣了,我們需要將他們的工作方法進行單獨的修改,那么這個修改的動作就是重寫。
定義:子類繼承父類后,如果子類的方法與父類的方法名稱、參數(shù)個數(shù)及返回值類型完全一致時,就稱為子類中的這個方法重寫了父類中的方法。同理,如果子類中重復(fù)定義了父類中的已有的屬性,則稱此子類中的屬性重寫了父類中的屬性。
子類重寫了父類的方法或?qū)傩裕敲丛摲椒ɑ驅(qū)傩员銓儆谧宇悾粚儆诟割悾绻€想調(diào)用父類中的被重寫的方法或?qū)傩裕褂胹uper.方法名/參數(shù)名的方式調(diào)用即可。
class Test{ publicstatic void main(String[] args){ DaoMangdm = new DaoMang(); dm.working(); Soujiusj = new Soujiu(); sj.working(); }} class Dog { Stringname; Stringage; void working(){ System.out.println("看家!"); }} class DaoMang extends Dog{ String id; voidqita(){ } voidworking(){ System.out.println("引路!"); }}class Soujiu extends Dog{ String id; voidworking(){ System.out.println("搜救!"); }}spuer關(guān)鍵字
定義: super代表當(dāng)前對象的父類對象。
當(dāng)創(chuàng)建子類對象,最先擁有的應(yīng)該是它的父類對象,那么可以使用super關(guān)鍵字代表父類對象,達到訪問父類成員的目的!
![]()
![]()
父類對象都沒有怎么可能創(chuàng)建子類對象?
子類覆蓋了父類的方法后,子類對象無法直接調(diào)用被覆蓋的父類中的方法,那么可以使用super關(guān)鍵字來實現(xiàn)調(diào)用父類的方法,或者也可以使用類名.方法名調(diào)用,但前提這個方法是靜態(tài)方法(類方法)。
通過super找到該對象的父類對象:
voidworking(){ super.working(); System.out.println("引路!"); }通過Dao.靜態(tài)方法執(zhí)行代碼:
static void working(){ Dog.working(); System.out.println("引路!"); }之前的this關(guān)鍵字是代表當(dāng)前對象本身。這個時候super代表的是父類對象本身。
同樣,super和this不能出現(xiàn)在static關(guān)鍵字修飾的方法中。
因為:static修飾的是靜態(tài)的,super、this關(guān)鍵字描述的是對象,靜態(tài)成員是優(yōu)先于對象存在的。用存在的東西訪問不存在的東西是錯誤的。

驗證:子類調(diào)用到父類的屬性,該屬性屬于父類而不屬于子類。
1、 %20在父類中定義name屬性,子類沒有定義name屬性。
2、 在測試時候,調(diào)用子類的name屬性。

3確定這個子類修改了的name屬性其實是屬于父類的!
證明:
1、 父類對象被子類引用。
2、 子類繼承父類的屬性,只是引用指向了父類,并沒有將父類的屬性進行單獨的復(fù)制一份作為子類對象本身的屬性。

導(dǎo)盲犬與搜救犬的父類對象是同一個嗎?
每次創(chuàng)建子類對象,都會單獨創(chuàng)建一個該子類的父類對象!他們的父類對象不是同一個,但是他們的父類是同一個!
調(diào)用父類構(gòu)造器:
class Dog { publicDog(String message){ System.out.println(message); } Stringname;} class DaoMang extends Dog{ publicDaoMang(){ super("abc"); } String id; static void working(){ System.out.println("引路!"); }}創(chuàng)建一個子類對象,發(fā)生了什么未知的事情?
class Test{ publicstatic void main(String[] args){ /* 創(chuàng)建子類對象發(fā)生了: 1、先執(zhí)行父類靜態(tài)代碼塊 2、執(zhí)行子類靜態(tài)代碼塊 3、執(zhí)行父類的構(gòu)造代碼塊 4、執(zhí)行父類的構(gòu)造方法 5、執(zhí)行子類的構(gòu)造代碼塊 6、執(zhí)行子類的構(gòu)造方法 */ DaoMangdm = new DaoMang(); }}class Dog { static{ System.out.println("Dog類的靜態(tài)代碼塊執(zhí)行了!"); } { System.out.println("創(chuàng)建Dog對象時構(gòu)造代碼塊"); } publicDog(){ System.out.println("Dog的構(gòu)造器執(zhí)行了!"); }} class DaoMang extends Dog{ static{ System.out.println("DaoMang類的靜態(tài)代碼塊執(zhí)行了!"); } { System.out.println("創(chuàng)建DaoMang對象時構(gòu)造代碼塊"); } publicDaoMang(){ System.out.println(id + "DaoMang的構(gòu)造器執(zhí)行了!"); }}
設(shè)置父類與子類同名的成員屬性
class Test{ publicstatic void main(String[] args){ DaoMangdm = new DaoMang(); dm.setName("金毛"); dm.setSuperName("SuperName"); Stringname = dm.getName(); StringsuperName = dm.getSuperName(); System.out.println("子類對象的name:" + name +"/n 父類對象的name是:" + superName); }}class Dog { Stringname;} class DaoMang extends Dog{ Stringname; publicvoid setName(String name){ this.name= name; } publicvoid setSuperName(String name){ super.name= name; } publicString getName(){ returnname; } publicString getSuperName(){ returnsuper.name; }}
新聞熱點
疑難解答