一累盗、繼承
- 概述
繼承是面向?qū)ο蟮闹匾卣髦唬敹鄠€類中存在相同的屬性和行為時突琳,將這些內(nèi)容抽取到單獨一個類中若债,那多個類中無需再定義這些屬性和行為,只需繼承那個單獨的類即可拆融。單獨的類稱為父類或超類
多個類稱為子類
例如:貓和老虎都是屬于貓科動物蠢琳。
描述貓啊终、老虎這些對象所創(chuàng)建的類,就是子類傲须;
而描述貓科動物這個對象所創(chuàng)建的類蓝牲,就是父類。
類與類之間存在了繼承關(guān)系泰讽,子類可以直接訪問父類中非私有的屬性和行為例衍,代碼中通過 extends 關(guān)鍵字來表示繼承關(guān)系。例如:class Son extends Father{}//代碼中的書寫格式
注:千萬不能為了獲取其他類中的功能菇绵,簡化代碼而去繼承肄渗。
必須是類與類之間有所屬關(guān)系才能繼承镇眷。
這種所屬關(guān)系的表示為 is a
- 特點
- 提高了代碼的復用性咬最。2. 讓類與類之間產(chǎn)生了關(guān)系,是多態(tài)的前提欠动。
注:Java 語言中只支持單繼承永乌,不支持多繼承。
Java 雖然不支持多繼承具伍,但是保留了類似的機制翅雏,并且以另一種形式來體現(xiàn),也就是多實現(xiàn)人芽。例如:一個兒子只能有一個父親望几。
只能單繼承的原因?因為類與類多繼承的話萤厅,容易產(chǎn)生安全隱患橄抹。例如:當多個父類中定義了相同的功能,但功能的內(nèi)容不相同時惕味,子類對象就無法確定要運行哪一個父類的功能了楼誓。
- 應(yīng)用
Java 中雖然不支持多繼承,但是支持多層繼承名挥,也就是繼承體系疟羹。例如:兒子繼承父親,父親繼承爺爺?shù)荣骶蟆lass A{}
class B extends A{}
class C extends B{}
如何使用繼承體系中的功能榄融?想要使用繼承體系,先要查詢繼承體系中父類的描述救湖,因為父類中定義的是該繼承體系中的共性功能剃袍,了解共性功能后,就可以知道該體系的基本功能捎谨,這個繼承體系就基本可以使用了民效。
具體調(diào)用時憔维,需要先創(chuàng)建最子類的對象,原因是畏邢?有可能父類不能創(chuàng)建對象业扒;
創(chuàng)建子類對象可以使用更多的功能,包括基本的父類共性功能舒萎,也包括子類的特有功能程储。總結(jié):查閱父類功能臂寝,創(chuàng)建子類對象使用功能章鲤。
例如:
子父類出現(xiàn)后,類成員(變量咆贬、函數(shù)败徊、構(gòu)造函數(shù))的特點:變量如果子類中出現(xiàn)非私有的同名成員變量時,子類要訪問本類中的變量掏缎,用 this皱蹦;子類要訪問父類父類中的同名變量,用 super眷蜈。
this 和 super 的使用幾乎一致沪哺,并且兩者都存于方法區(qū)中。this 表示本類對象的引用
super 表示父類對象的引用
函數(shù) —— 重寫(覆蓋)當子類出現(xiàn)和父類一模一樣的函數(shù)時酌儒,子類對象調(diào)用該函數(shù)辜妓,會運行子類的函數(shù)內(nèi)容,相當于父類的函數(shù)被覆蓋了忌怎,這就是函數(shù)的一個特性:重寫(覆蓋)籍滴。
當子類繼承父類,并且沿襲了父類的功能時呆躲,子類雖具備父類的該功能异逐,但是子類中功能的內(nèi)容卻和父類不一致,這時插掂,無需重新定義新功能灰瞻,而是使用重寫(覆蓋)這一特性,保留父類的功能辅甥,并重寫子類的功能內(nèi)容酝润,子類中同時想具有父類函數(shù)中的內(nèi)容時,可以使用 super.() 方法璃弄。
在上面例子中的 Student 類中重寫 sleep() 方法要销,如下:
注:
- 靜態(tài)只能覆蓋靜態(tài)。2. 父類中的私有方法不能被重寫(覆蓋)夏块。3. 子類重寫(覆蓋)父類疏咐,必須保證子類權(quán)限大于或等于父類權(quán)限纤掸,才可以重寫(覆蓋),否則會導致編譯失敗浑塞。
重寫(覆蓋)與重載的區(qū)別:重寫(覆蓋):子父類方法要一模一樣借跪。
重載:只看同名函數(shù)的參數(shù)列表。
構(gòu)造函數(shù)對子類對象進行初始化時酌壕,父類的構(gòu)造函數(shù)也會運行掏愁,因為子類的每一個構(gòu)造函數(shù)默認第一行都有一條隱式的語句 super();
super():訪問父類中空參數(shù)的構(gòu)造函數(shù),而且子類中所有構(gòu)造函數(shù)默認第一行都是 super();
子類為什么一定會訪問父類的構(gòu)造函數(shù)卵牍?父類中的數(shù)據(jù)子類可以直接獲取果港,子類對象在建立時,需先查看父類中是如何對這些數(shù)據(jù)進行初始化的糊昙,因此子類在對象初始化時辛掠,需要先訪問父類中的構(gòu)造函數(shù)。
為什么 super() 和 this() 不能在同一個構(gòu)造函數(shù)中溅蛉?因為不能在同一行公浪。
為什么 super() 和 this() 不能在同一行他宛?因為需要先做初始化動作船侧,在子類構(gòu)造函數(shù)中必須有一個 super 語句或 this 語句。
注:super 語句一定是定義在子類構(gòu)造函數(shù)中的第一行厅各。
如果要訪問父類中指定的構(gòu)造函數(shù)镜撩,可以通過手動定義 super 語句的方式去指定。
總結(jié):
- 子類中所有構(gòu)造函數(shù)队塘,默認都會訪問父類的空參數(shù)構(gòu)造函數(shù)袁梗;2. 子類中每一個構(gòu)造函數(shù)中的第一行都有一句隱式 super(); 語句;3. 父類沒有空參數(shù)構(gòu)造函數(shù)時憔古,子類必須手動定義 super 語句或 this 語句形式去指定要訪問的構(gòu)造函數(shù)遮怜;4. 子類的構(gòu)造函數(shù)第一行也可以手動指定 this 語句去訪問本類中的其它構(gòu)造函數(shù);5. 子類中至少會有一個構(gòu)造函數(shù)會訪問父類中的構(gòu)造函數(shù)鸿市。
final 關(guān)鍵字由于繼承的出現(xiàn)锯梁,打破了對象的封裝性,使得子類可以隨意重寫(覆蓋)父類的功能焰情,這也是繼承的弊端陌凳。為了解決繼承的這個弊端,便出現(xiàn)了 final(最終)關(guān)鍵字内舟。
final 修飾符的特點:
- 可以修飾類合敦、函數(shù)、變量验游。2. final 修飾的類不能被繼承充岛。(可以避免被繼承保檐、被子類重寫父類函數(shù)功能)3. final 修飾的方法不能被重寫。4. final 修飾的變量是常量崔梗,并且只能賦值一次展东,可以修飾成員變量,也可以修飾局部變量炒俱。5. 內(nèi)部類定義在類中的局部位置時盐肃,只能訪問該局部被 final 修飾的局部變量。
二权悟、抽象
- 概述
從多個事物中將共性的砸王、本質(zhì)的內(nèi)容抽取出來,這就是抽象峦阁。例如:狗和狼共性都是犬科谦铃,犬科就是抽象出來的概念。
Java 中可以定義沒有方法體的方法榔昔,方法的具體實現(xiàn)由子類實現(xiàn)驹闰,多個對象如果具有相同功能,但功能的具體內(nèi)容有所不同撒会,那么在抽取過程中嘹朗,只抽取功能定義,未抽取功能主體內(nèi)容诵肛,這樣只有功能聲明屹培,沒有功能主體的方法,這樣的方法稱為抽象方法怔檩,而含有抽象方法的類稱為抽象類褪秀。例如:狗和狼都有吼叫的方法,但是吼叫的內(nèi)容不一樣薛训,因此抽象出來的犬科雖然有吼叫功能媒吗,但是并沒有明確吼叫的實現(xiàn)內(nèi)容細節(jié)。
格式:abstract 類名 {}
子類名 extends 抽象類名 {}
- 特點
抽象類和抽象方法必須使用 abstract 關(guān)鍵字進行修飾乙埃。
抽象方法只有方法聲明闸英,沒有方法體,定義在抽象類中膊爪。格式:修飾符 abstract 返回值類型 函數(shù)名(參數(shù)列表);
抽象類不能被實例化自阱,也就是說不能用 new 創(chuàng)建對象,抽象類是從具體事物抽取出來的米酬,抽象類本身是不具體的沛豌,沒有對應(yīng)的實例。例如:犬科是一個抽象的概念,真正存在的實例是狗和狼加派。
抽象類通過其子類進行實例化叫确,子類必須重寫(覆蓋)抽象類中所有的抽象方法,子類才能實例化芍锦,否則該子類也會是抽象類竹勉。
注:抽象類中可以存在非抽象方法。
- 抽象類與一般類
區(qū)別:抽象類不可以實例化娄琉。
抽象類不能創(chuàng)建對象次乓,但是也有構(gòu)造函數(shù),提供給子類實例化調(diào)用孽水。
抽象類比一般類多了抽象方法票腰,抽象類中可以定義抽象方法,也可以定義非抽象方法女气。
注:抽象類中可以不定義抽象方法杏慰,使抽象類不被實例化,常用于模塊設(shè)計炼鞠。
被 abstract 修飾的函數(shù)不能同時被 private缘滥、static、final 修飾谒主。private:抽象類中的抽象方法需要被子類重寫朝扼,而 private 修飾的方法是私有的,不被子類所知瘩将,無法重寫吟税。
static:static 修飾的方法可以直接使用類名調(diào)用凹耙,不需要使用對象調(diào)用姿现,如果 static 使用在抽象方法上就沒有運行的意義了。
final:final 修飾的類不能有子類肖抱,而 abstract 修飾的類一定是一個父類备典。
三、接口
- 概述
當抽象類中所有的方法都是抽象方法時意述,該類可以通過接口的形式表示提佣,使用 interface 來表示,子類中使用 implements 來實現(xiàn)荤崇,接口可以認為是特殊的抽象類拌屏。
格式:interface 接口名{}
子類名 implements 接口名 {}
特點:接口中常見定義:常量、抽象方法术荤。
接口中成員都是使用 public 修飾的倚喂。
接口中成員都有固定的修飾符:常量:public static final
方法:public abstract
注:接口中的常量可以不寫 public static final,方法可以不寫 public abstract瓣戚,編譯時會自動添加這些修飾符端圈,這是 Java 中接口固定的修飾符焦读,為了方便閱讀,一般都會寫上舱权。
特點
接口是程序功能的擴展矗晃。
接口是對外暴露的規(guī)則。
接口的出現(xiàn)降低了耦合性宴倍。
接口可以用來多實現(xiàn)张症,對于 Java 不支持多繼承的缺陷而做的轉(zhuǎn)換,Java 支持多實現(xiàn)鸵贬。
類與接口之間是實現(xiàn)關(guān)系吠冤,類只能繼承一個類,但同時可以實現(xiàn)多個接口恭理。
接口與接口之間可以有繼承關(guān)系拯辙,而且接口與接口之間支持多繼承。
注: 1. 接口不可以創(chuàng)建對象颜价,因為接口有抽象方法需要子類實現(xiàn)(implements)涯保,子類需要全部重寫接口中的抽象方法后,子類才能實例化周伦,否則該子類也會是抽象類夕春。 2. 實現(xiàn)多個接口時,接口中不允許有返回類型不同的同名抽象函數(shù)专挪,如果有這樣的情況時及志,子類實現(xiàn)將無法重寫接口的抽象方法。接口與抽象類
相同點:都是不斷向上抽取出來的抽象概念寨腔。
區(qū)別:接口是實現(xiàn)速侈,是 "like a" 關(guān)系;
抽象類是繼承迫卢,是 "is a" 關(guān)系倚搬。
接口中的常量和方法都是 public 修飾的權(quán)限;
抽象類中可以有私有變量或方法乾蛤。
接口體現(xiàn)的是實現(xiàn)關(guān)系每界,可以多實現(xiàn),接口與接口之間可以有繼承關(guān)系家卖;
抽象類體現(xiàn)的是繼承關(guān)系眨层,只能單繼承。
接口中所有方法都是抽象方法上荡,接口中的成員都是有固定的修飾符趴樱;
抽象類中可以定義非抽象方法,提供給子類直接使用。