Java中的繼承關(guān)系與方法覆蓋
什么是繼承關(guān)系?
基于某個(gè)父類(lèi)對(duì)象定義的加以拓展,從而產(chǎn)生新的子類(lèi)定義,子類(lèi)可以繼承父類(lèi)原來(lái)的某些定義,也可以增加原來(lái)父類(lèi)沒(méi)有的定義,或者覆寫(xiě)父類(lèi)中的某些特性。
從面向?qū)ο蟮慕嵌壬蟻?lái)說(shuō),繼承是一種從一般到特殊的關(guān)系,是一種“ is a ”的關(guān)系,即子類(lèi)是父類(lèi)的拓展,是一種特殊的父類(lèi),比如狗是動(dòng)物的一種特殊情況,狗屬于動(dòng)物。
在Java語(yǔ)言當(dāng)中,存在多個(gè)類(lèi)的時(shí)候,我們使用“extends”關(guān)鍵字來(lái)表示子類(lèi)和父類(lèi)之間的關(guān)系。
在Java語(yǔ)言當(dāng)中,類(lèi)和類(lèi)之間的繼承關(guān)系,只允許單繼承,不允許多繼承,也就是說(shuō)一個(gè)類(lèi)A,只能有一個(gè)直接的父類(lèi),不能出現(xiàn)A類(lèi)同時(shí)繼承于類(lèi)B和類(lèi)C,但是在Java中,允許多重繼承。
多重繼承的例子:
動(dòng)物有胎生和孿生之分,胎生動(dòng)物有老虎,老虎又分華南虎,東本虎,孟加拉虎等。
在Java中除了Object類(lèi)之外,每一個(gè)類(lèi)都有一個(gè)直接的父類(lèi)
比如:class Student extends Person{}
我們就說(shuō)此時(shí)的Student的直接父類(lèi)是Person,那么Person的父類(lèi)又是誰(shuí)呢?
Object類(lèi)是Java語(yǔ)言的根類(lèi)(老祖宗,任何類(lèi)都是Object的子類(lèi))
class Person{}等價(jià)與 class Person extend Object{}
Object類(lèi)要么是一個(gè)類(lèi)直接父類(lèi),要么是一個(gè)類(lèi)間接父類(lèi)
繼承關(guān)系的作用
(1)解決了代碼重復(fù)的問(wèn)題
(2)真正的作用,表現(xiàn)出了一個(gè)體系。
子類(lèi)可以繼承哪些父類(lèi)成員?
子類(lèi)繼承父類(lèi)之后,可以擁有父類(lèi)的某一些狀態(tài)和行為(子類(lèi)復(fù)用了父類(lèi)的功能或狀態(tài))
子類(lèi)到底繼承了父類(lèi)的哪些成員(根據(jù)訪問(wèn)修飾符來(lái)判斷):
(1)如果父類(lèi)中的成員使用public修飾,子類(lèi)繼承;
(2)如果父類(lèi)中的成員使用protected修飾,子類(lèi)也繼承,即使父類(lèi)和子類(lèi)不在同一個(gè)包中;
(3)如果父類(lèi)和子類(lèi)在同一個(gè)包中,此時(shí)的子類(lèi)可有繼承父類(lèi)中缺省修飾符的成員;
(4)如果父類(lèi)中的成員使用private修飾,子類(lèi)打死都繼承不到,因?yàn)閜rivate只能在本類(lèi)中訪問(wèn);
(5)父類(lèi)的構(gòu)造器,子類(lèi)也不能繼承,因?yàn)闃?gòu)造器必須和當(dāng)前的類(lèi)名相同。
方法覆蓋(復(fù)寫(xiě)/覆寫(xiě))
子類(lèi)拓展了父類(lèi),可以或得父類(lèi)的部分方法和成員變量??墒钱?dāng)父類(lèi)的某個(gè)方法不適合本身的特征時(shí),此時(shí)怎么辦?
如:企鵝和鴕鳥(niǎo)是鳥(niǎo)中一個(gè)特殊品種,所以企鵝/鴕鳥(niǎo)是鳥(niǎo)類(lèi)的一個(gè)子類(lèi),但是鳥(niǎo)類(lèi)有飛翔的功能,但是對(duì)應(yīng)于企鵝/鴕鳥(niǎo),飛翔的行為顯然不適合它。
這個(gè)時(shí)候就用到了方法覆蓋,如下代碼。
創(chuàng)建了一個(gè)子類(lèi)對(duì)象Penguin ,并調(diào)用fly方法。這個(gè)過(guò)程其實(shí)是先從子類(lèi)中去尋找fly方法,如果找到就執(zhí)行,若是找不到,則繼續(xù)去父類(lèi)中去找。
//鳥(niǎo)類(lèi)
clas Bird{
public void fly(){
System.out.println("我可以飛翔");
}
}
//企鵝類(lèi)
class Penguin extends Bird{
// 重新定義了fly行為
public void fly(){
System.out.println("我不可以飛翔");
}
}
方法覆蓋的原則(一同兩小一大):Override
一同:
(1)實(shí)例方法簽名必須相同(方法簽名=方法名+方法的參數(shù)列表)
兩?。?/strong>
(2)子類(lèi)方法的返回值類(lèi)型是和父類(lèi)方法的返回類(lèi)型相同或者其子類(lèi);
或者說(shuō),子類(lèi)可以返回一個(gè)更加具體的類(lèi)。如下代碼:
但是在實(shí)際開(kāi)發(fā)中,沒(méi)必要這樣做,直接使用(1)敘述的就行了
class Bird
{
public Object fly(){
System.out.println("fly");
return null;
}
}
class Penguin extends Bird
{
public String fly(){
System.out.println("Can't fly");
return "xxx";
}
}
(3)子類(lèi)方法聲明拋出的異常類(lèi)型和父類(lèi)聲明拋出的異常類(lèi)型相同或者是其子類(lèi)。
子類(lèi)方法聲明拋出的異常類(lèi)型小于或等于父類(lèi)方法聲明拋出的異常類(lèi)型;
子類(lèi)方法可以同時(shí)聲明拋出多個(gè)屬于父類(lèi)方法聲明拋出異常類(lèi)的子類(lèi)(RuntimeExcption類(lèi)型除外);
一大:
(4)子類(lèi)方法的訪問(wèn)權(quán)限比父類(lèi)方法的訪問(wèn)權(quán)限更大或相等。
class Person
{
public void fly(){
System.out.println("fly");
}
}
class Student extends Person
{
// 編譯報(bào)錯(cuò),子類(lèi)方法的訪問(wèn)權(quán)限要比父類(lèi)方法的訪問(wèn)權(quán)限更大或相等。
void fly(){
System.out.println("Can't fly");
}
}
private修飾的方法不能被子類(lèi)所繼承,也就不存在覆蓋的概念。
判斷是否覆蓋方法的必殺技:@Override標(biāo)簽:若方法是復(fù)寫(xiě)方法,在方法前或上貼上該標(biāo)簽,編譯通過(guò),否則,編譯出錯(cuò)。
class Person
{
private void fly(){
System.out.println("fly");
}
}
class Student extends Person
{
@Override
public void fly(){
System.out.println("Can't fly");
}
}
---------- 編譯java ----------
ExtendsDemo.java:10: 錯(cuò)誤: 方法不會(huì)覆蓋或?qū)崿F(xiàn)超類(lèi)型的方法
@Override
^
1 個(gè)錯(cuò)誤輸出完成 (耗時(shí) 0 秒) - 正常終止
注意:
1. 只有方法存在覆蓋的概念,字段沒(méi)有覆蓋。
2. 方法覆蓋解決的問(wèn)題:當(dāng)父類(lèi)的某一個(gè)行為不符合子類(lèi)具體的特征時(shí),此時(shí)子類(lèi)需要重新定義父類(lèi)
方法的重載與覆蓋的區(qū)別
- 方法重載(Overload)
- 方法重寫(xiě)(Override)
二者本身沒(méi)有一點(diǎn)關(guān)系,僅僅只是名字很像
方法的重寫(xiě)
作用:
解決子類(lèi)繼承父類(lèi)之后,可能父類(lèi)的某一個(gè)方法不再滿(mǎn)足子類(lèi)的具體特征,此時(shí)需要重新定義子類(lèi)中定義的該方法,并重寫(xiě)方法體;
規(guī)則:
1.參數(shù)列表必須完全與被重寫(xiě)方法的相同;
2.返回類(lèi)型必須完全與被重寫(xiě)方法的返回類(lèi)型相同;
3.訪問(wèn)權(quán)限不能比父類(lèi)中被重寫(xiě)的方法的訪問(wèn)權(quán)限更低。例如:如果父類(lèi)的一個(gè)方法被聲明為public,那么在子類(lèi)中重寫(xiě)該方法就不能聲明為protected。
4.父類(lèi)的成員方法只能被它的子類(lèi)重寫(xiě)。
5.聲明為final的方法不能被重寫(xiě)。
6.聲明為static的方法不能被重寫(xiě),但是能夠被再次聲明。
7.子類(lèi)和父類(lèi)在同一個(gè)包中,那么子類(lèi)可以重寫(xiě)父類(lèi)所有方法,除了聲明為private和final的方法。
8.子類(lèi)和父類(lèi)不在同一個(gè)包中,那么子類(lèi)只能夠重寫(xiě)父類(lèi)的聲明為public和protected的非final方法。
9.重寫(xiě)的方法能夠拋出任何非強(qiáng)制異常,無(wú)論被重寫(xiě)的方法是否拋出異常。但是,重寫(xiě)的方法不能拋出新的強(qiáng)制性異常,或者比被重寫(xiě)方法聲明的更廣泛的強(qiáng)制性異常,反之則可以。
10.構(gòu)造方法不能被重寫(xiě)。
11.如果不能繼承一個(gè)方法,則不能重寫(xiě)這個(gè)方法。
重載
作用:
重載(overloading) 是在一個(gè)類(lèi)里面,方法名字相同,而參數(shù)不同。返回類(lèi)型可以相同也可以不同。
每個(gè)重載的方法(或者構(gòu)造函數(shù))都必須有一個(gè)獨(dú)一無(wú)二的參數(shù)類(lèi)型列表。
最常用的地方就是構(gòu)造器的重載。
規(guī)則:
1.被重載的方法必須改變參數(shù)列表(參數(shù)個(gè)數(shù)或類(lèi)型不一樣);
2.被重載的方法可以改變返回類(lèi)型;
3.被重載的方法可以改變?cè)L問(wèn)修飾符;
4.被重載的方法可以聲明新的或更廣的檢查異常;
5.方法能夠在同一個(gè)類(lèi)中或者在一個(gè)子類(lèi)中被重載。
6.無(wú)法以返回值類(lèi)型作為重載函數(shù)的區(qū)分標(biāo)準(zhǔn)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決Idea啟動(dòng)錯(cuò)誤-java.lang.OutOfMemoryError:內(nèi)存不足錯(cuò)誤。
在Java開(kāi)發(fā)過(guò)程中,有時(shí)我們會(huì)遇到j(luò)ava.lang.OutOfMemoryError這樣的錯(cuò)誤,這篇文章主要介紹了解決Idea啟動(dòng)錯(cuò)誤-java.lang.OutOfMemoryError:內(nèi)存不足錯(cuò)誤,的相關(guān)資料,需要的朋友可以參考下2025-11-11
AQS實(shí)現(xiàn)的ReentrantLock全過(guò)程
這篇文章主要介紹了AQS實(shí)現(xiàn)的ReentrantLock全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2026-03-03
jwt原理及Java中實(shí)現(xiàn)過(guò)程
JWT是無(wú)狀態(tài)認(rèn)證的JSON令牌,包含頭部、載荷和簽名,用于身份驗(yàn)證與權(quán)限管理,需注意設(shè)置過(guò)期時(shí)間、使用非對(duì)稱(chēng)算法、安全存儲(chǔ)傳輸,及合理刷新策略,確保系統(tǒng)安全與效率2025-08-08
Java并發(fā)之條件阻塞Condition的應(yīng)用代碼示例
這篇文章主要介紹了Java并發(fā)之條件阻塞Condition的應(yīng)用代碼示例,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02
為什么在重寫(xiě) equals方法的同時(shí)必須重寫(xiě) hashcode方法
Object 類(lèi)是所有類(lèi)的父類(lèi),其 equals 方法比較的是兩個(gè)對(duì)象的引用指向的地址,hashcode 是一個(gè)本地方法,返回的是對(duì)象地址值。他們都是通過(guò)比較地址來(lái)比較對(duì)象是否相等的2016-07-07
mybatis-plus QueryWrapper 添加limit方式
這篇文章主要介紹了mybatis-plus QueryWrapper 添加limit方式,具有很好的參考價(jià)值,希望對(duì)大家有所2022-01-01
Java中的Semaphore計(jì)數(shù)信號(hào)量詳細(xì)解析
這篇文章主要介紹了Java中的Semaphore計(jì)數(shù)信號(hào)量詳細(xì)解析,Semaphore?是一個(gè)計(jì)數(shù)信號(hào)量,必須由獲取它的線(xiàn)程釋放,常用于限制可以訪問(wèn)某些資源的線(xiàn)程數(shù)量,例如通過(guò)?Semaphore?限流,需要的朋友可以參考下2023-11-11

