面向?qū)ο笕蠡悍庋b,繼承,多態(tài)。面試會(huì)問(wèn)到。
Overriding 覆蓋 只存在于父子類之間,一定。
什么時(shí)候才是覆蓋呢?
class Father{
public void run(){
}
}
class Son extends Father{
public void run(int a){
}
}
注意:這是方法的重載,不是覆蓋!只是這個(gè)重載發(fā)生在父子類之間。
覆蓋是,子類參數(shù)列表與返回值都與父類相同,并且子類在覆蓋父類方法時(shí),不能給出更嚴(yán)格的訪問(wèn)控制,并且子類方法例外的類型是等于父子方法拋出的異常類型,或者是其子類型。
The exceptions thrown by an overriding method must be equal to or a subset of the exceptions thrown by the overridden method.
注意構(gòu)造方法根本不能繼承,所以不存在覆蓋的問(wèn)題。
訪問(wèn)控制
private 本類內(nèi)部可見
default 同類同包
protected 同包+不同包子類
要構(gòu)造一個(gè)對(duì)象,先構(gòu)造父類對(duì)象,再構(gòu)造子類對(duì)象
構(gòu)造一個(gè)對(duì)象的執(zhí)行過(guò)程。
1.遞歸的構(gòu)造父類對(duì)象-----------〉也就是說(shuō)父類本身也要走這樣的步驟。
2.順序調(diào)用成員屬性賦初值語(yǔ)句
3.調(diào)用本類構(gòu)造方法
后來(lái)課程領(lǐng)悟,類加載與構(gòu)造對(duì)象是兩回事,類加載過(guò)程,1.static靜態(tài)成員加載,2運(yùn)行static一次,靜態(tài)代碼塊,3如果有靜態(tài)內(nèi)部類,賦值,對(duì)靜態(tài)內(nèi)部類的賦值是指編譯產(chǎn)生的Employee$SomeInner.class文件的讀取。
如果類有靜態(tài)變量或者靜態(tài)塊,而且用到時(shí)(static初始化只有在必要的時(shí)候才會(huì)進(jìn)行),那么就會(huì)在第一步之前執(zhí)行一遍,先靜態(tài)變量,然后靜態(tài)塊,以后再怎么new都不會(huì)執(zhí)行,回到創(chuàng)建父類開始。
======〉引用Think In Java
在這里有必要總結(jié)一下對(duì)象的創(chuàng)建過(guò)程。請(qǐng)考慮一個(gè)名為Dog的類:
(1) 類型為Dog的一個(gè)對(duì)象首次創(chuàng)建時(shí),或者Dog類的static方法/static字段首次訪問(wèn)時(shí),Java解釋器必須找到Dog.class(在事先設(shè)好的類路徑里搜索)。
(2) 找到Dog.class后(它會(huì)創(chuàng)建一個(gè)Class對(duì)象,這將在后面學(xué)到),它的所有static初始化模塊都會(huì)運(yùn)行。因此,static初始化僅發(fā)生一次——在Class對(duì)象首次載入的時(shí)候。
(3) 創(chuàng)建一個(gè)new Dog()時(shí),Dog對(duì)象的構(gòu)建進(jìn)程首先會(huì)在內(nèi)存堆(Heap)里為一個(gè)Dog對(duì)象分配足夠多的存儲(chǔ)空間。
(4) 這種存儲(chǔ)空間會(huì)清為零,將Dog中的所有基本類型設(shè)為它們的默認(rèn)值(零用于數(shù)字,以及boolean和char的等價(jià)設(shè)定)。
(5) 進(jìn)行字段定義時(shí)發(fā)生的所有初始化都會(huì)執(zhí)行。
(6) 執(zhí)行構(gòu)建器。正如第6章將要講到的那樣,這實(shí)際可能要求進(jìn)行相當(dāng)多的操作,特別是在涉及繼承的時(shí)候。
=====================
多態(tài)-1.編譯時(shí)多態(tài) 方法重載
2.運(yùn)行時(shí)多態(tài) 一個(gè)對(duì)象可能會(huì)具有多個(gè)類型
對(duì)象是客觀的。
人類對(duì)對(duì)象的認(rèn)識(shí)是主觀的
當(dāng)人看到一個(gè)不能識(shí)別的,有生命的,區(qū)別人的東西時(shí),會(huì)類來(lái)認(rèn)識(shí)該事物。
也就是Animal a = new Dog();子類對(duì)象可以使用父類對(duì)象來(lái)引用。
Animal被稱為編譯時(shí)類型,而a真正的對(duì)象類型是運(yùn)行時(shí)類型。
3個(gè)原則:
1.對(duì)象不變(運(yùn)行時(shí)類型不變)(客觀的肯定不會(huì)改變)
2.只能調(diào)用編譯時(shí)類型的方法,方法調(diào)用時(shí),檢查編譯時(shí)類型內(nèi)部是否定義了該方法。
也就是說(shuō),在你以一個(gè)一個(gè)動(dòng)物來(lái)看待一只狗時(shí),你是不會(huì)知道它有散步的方法的。
3.RTTI,運(yùn)行時(shí),動(dòng)態(tài)類型判定(看運(yùn)行時(shí)類型),子類覆蓋了(Overriding)父類方法,那么調(diào)用運(yùn)行時(shí)類型對(duì)象的方法。
a instanceof 類名(編譯時(shí)類型)
a為對(duì)象變量
判斷a是否被聲明為后面類的對(duì)象。
用在強(qiáng)制類型轉(zhuǎn)換之前。如果轉(zhuǎn)換錯(cuò)了,java.lang.ClassCastException 運(yùn)行時(shí)例外
記住,方法只有覆蓋時(shí),調(diào)用尋找運(yùn)行時(shí)類型。而Overloading ->編譯時(shí)多態(tài)->看編譯時(shí)類型。
屬性,重載阿,都要看編譯時(shí)類型。
































為什么子類覆蓋父類方法時(shí),訪問(wèn)控制符只能更寬泛。因?yàn)槿绻割惙椒閜ublic,子類方法為private,那么多態(tài)時(shí),察看父類方法可以調(diào)用(可調(diào)用編譯時(shí)類型所定義的方法),而動(dòng)態(tài)類型判斷時(shí),調(diào)用子類方法,發(fā)現(xiàn)為private,完蛋了。