畢向東Java基礎(chǔ)教程-繼承【上】

概述

  • 多個(gè)類中存在相同屬性和行為時(shí)宪卿,將這些內(nèi)容抽取到單獨(dú)一個(gè)類中,那么多個(gè)類無需再定義這些屬性和行為望众,只要繼承單獨(dú)的類即可匪补。
  • 多個(gè)類可以稱為子類,單獨(dú)的類稱為父類或者超類烂翰。
  • 子類可以訪問父類中的<font color="#FF0000">非私有的</font>屬性和行為夯缺。
  • 通過extends關(guān)鍵字讓類與類之間產(chǎn)生繼承關(guān)系。
    class SubDemo extends Demo{}
  • 繼承的好處:
    繼承的出現(xiàn)提高了代碼的復(fù)用性刽酱。
    繼承的出現(xiàn)讓類與類之間產(chǎn)生了關(guān)系喳逛,提供了多態(tài)的前提。

特點(diǎn)

  • Java中支持單繼承棵里,不支持多繼承
    一個(gè)子類只能有一個(gè)直接父類润文,否則若多個(gè)父類中有相同成員,會產(chǎn)生調(diào)用的不確定性殿怜。

    class SubDemo extends Demo{} //ok
    class SubDemo extends Demo1,Demo2...{} //error
    
  • Java支持多層繼承(繼承體系)

    class A{}
    class B extends A{}
    class C extends B{} 
    

    當(dāng)要使用一個(gè)繼承體系時(shí):
    1)查看該體系中的頂層類典蝌,了解該體系的基本功能
    2)創(chuàng)建體系中的最子類對象,完成功能的使用

  • 什么時(shí)候定義繼承头谜?
    當(dāng)類與類之間存在著所屬("is a")關(guān)系的時(shí)候骏掀,就定義繼承。如xxx是yyy的一種柱告,則xxx extends yyy截驮。或者判斷父類中的功能是否子類都應(yīng)該具備际度,若有些不具備葵袭,則不存在繼承。不要僅為了獲取其他類中某個(gè)功能而去繼承 乖菱。

super關(guān)鍵字

this和super的用法很相似坡锡。

  • this代表一個(gè)本類對象的引用蓬网;super代表一個(gè)<font color="#FF0000">父類空間</font>(注意并不是代表父類對象,如下代碼鹉勒,從未定義過父類對象帆锋,子類之所以可以獲取父類的內(nèi)容,是因?yàn)槠涑钟衧uper引用)禽额。

  • 當(dāng)本類中的成員和局部變量同名用this區(qū)分锯厢;當(dāng)子父類中的成員變量同名用super區(qū)分父類(如果不使用super,則默認(rèn)調(diào)用子類自己的成員變量)脯倒,子類要調(diào)用父類構(gòu)造函數(shù)時(shí)哲鸳,可以使用super關(guān)鍵字。

    Example1

    public class Father 
    {    
        int num = 4;
    }
    class Son extends Father{
        int num = 5;
        void show()
        {
            System.out.println(this.num+"..."+super.num);
        }
    }
    class Demo
    {
        public static void main(String[] args)
        {
            Son s = new Son();
            s.show();
        }
    }
    

    父類比子類先加載盔憨。

注意:
問題:父類中的私有內(nèi)容徙菠,子類是否具備——實(shí)際上子類對于父類中私有的成員變量是繼承了的,即定義子類對象時(shí)郁岩,在堆中存有父類的私有成員變量(上圖堆中fu的方框內(nèi))婿奔,只是不能直接訪問,所以確切地說问慎,應(yīng)該是子類中不能直接地訪問父類中的私有內(nèi)容萍摊。

Example2

class Person
{
    private String name;
    private int age;

    Person(String name, int age)
    {
        this.name = name;
        this.age = age;
    }
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
}

class Student extends Person
{
    Student(String name, int age)
    {
        super(name, age);//調(diào)用父類的構(gòu)造函數(shù)
    }
}
class Worker extends Person
{
    Worker(String name, int age)
    {
        super(name, age);//調(diào)用父類的構(gòu)造函數(shù)
    }
}

函數(shù)覆蓋(Override)

  • 函數(shù)覆蓋發(fā)生在父類與子類之間,其函數(shù)名如叼、參數(shù)類型冰木、返回值類型必須同父類中的相對應(yīng)被覆蓋的函數(shù)嚴(yán)格一致,覆蓋函數(shù)和被覆蓋函數(shù)只有函數(shù)體不同笼恰,當(dāng)派生類對象調(diào)用子類中該同名函數(shù)時(shí)會自動調(diào)用子類中的覆蓋版本踊沸,而不是父類中的被覆蓋函數(shù)版本,這種機(jī)制就叫做函數(shù)覆蓋社证。
  • 父類中的私有方法不可以被覆蓋逼龟。
  • 在子類覆蓋方法中,繼續(xù)使用被覆蓋的方法可以通過super.函數(shù)名獲取追葡。
  • 覆蓋注意事項(xiàng):
    覆蓋時(shí)腺律,子類方法權(quán)限一定要大于等于父類方法權(quán)限。
    靜態(tài)只能覆蓋靜態(tài)宜肉,或被靜態(tài)覆蓋(非靜態(tài)不能覆蓋靜態(tài)匀钧,靜態(tài)不能覆蓋非靜態(tài),否則會報(bào)編譯錯(cuò))谬返。
  • 覆蓋的應(yīng)用:
    當(dāng)子類需要父類的功能之斯,而功能主體子類有自己特有內(nèi)容時(shí),可以復(fù)寫父類中的方法朱浴,這樣即沿襲了父類的功能吊圾,又定義了子類特有的內(nèi)容。

子類的實(shí)例化過程

注意構(gòu)造函數(shù)不會繼承更不會覆蓋(首先函數(shù)名都不一樣...
子類的實(shí)例化過程:子類中所有的構(gòu)造函數(shù)默認(rèn)都會訪問父類中空參數(shù)的構(gòu)造函數(shù)(因?yàn)槊恳粋€(gè)構(gòu)造函數(shù)的第一行都有一條默認(rèn)的語句super()翰蠢;之所以會有這樣一條默認(rèn)語句项乒,是因?yàn)樽宇惱^承了父類,獲取到了父類中的內(nèi)容(屬性)梁沧,所以在使用父類內(nèi)容之前檀何,要先明確父類是如何對這些數(shù)據(jù)初始化的)。

public class Father 
{
    public Father()
    {
        System.out.println("Father run");
    }
}
class Son extends Father
{
    public Son()
    {
        //super(); //默認(rèn)會調(diào)用父類的空參構(gòu)造函數(shù)
        System.out.println("Son run");
    }
}

當(dāng)父類中沒有空參數(shù)的構(gòu)造函數(shù)時(shí)廷支,子類的構(gòu)造函數(shù)必須通過this或者super語句指定要訪問的構(gòu)造函數(shù)频鉴。
注意:super語句必須要定義在子類構(gòu)造函數(shù)的第一行,因?yàn)楦割惖某跏蓟瘎幼饕韧瓿伞?br> 如果子類構(gòu)造函數(shù)中使用this調(diào)用了本類構(gòu)造函數(shù)恋拍,那么就沒有super了垛孔,因?yàn)閟uper和this都只能定義在第一行。但是可以保證的是施敢,子類中肯定會有其他的構(gòu)造函數(shù)訪問父類的構(gòu)造函數(shù)周荐,即子類構(gòu)造函數(shù)中至少有一個(gè)訪問父類構(gòu)造函數(shù)。

public class Father 
{
    public Father(int num)
    {
        System.out.println("Father run");
    }
}
class Son extends Father
{
    public Son()
    {
        this(4);
    }

    public Son(int num)
    {
        super(num);
        System.out.println("Son run");
    }

}

注意僵娃,類默認(rèn)的空參構(gòu)造函數(shù)的修飾符與類保持一致概作。

class Demo
{
    /*
    Demo()
    {
        super(); //父類為Object
        return;
    }
    */
}

Example1:子類的實(shí)例化過程

public class Father {
    Father()
    {
        show();
    }
    public  void show()
    {
        System.out.println("father show");
    }
}
class Son extends Father
{
    int num = 8;
    Son()
    {
        super();
        //分水嶺
        System.out.println("Son run..." + num);
    }

    public void show()
    {
        System.out.println("Son show..." + num);
    }
}
class Demo
{
    public static void main(String[] args)
    {
        Son s = new Son();
        s.show();
    }
}

輸出結(jié)果為:

Son show...0
Son run...8
Son show...8

內(nèi)存圖解:

默認(rèn)初始化,成員變量num=0默怨;顯示初始化讯榕,成員變量num=8。
默認(rèn)初始化后匙睹,執(zhí)行super()愚屁,經(jīng)過父類構(gòu)造函數(shù)初始化,再進(jìn)行自己的顯示初始化痕檬,最后是自己的構(gòu)造函數(shù)初始化集绰。

注意,若子類當(dāng)中有構(gòu)造代碼塊谆棺,則其初始化的過程為:

一個(gè)對象的實(shí)例化過程:

Person p = new Person();
1栽燕、JVM讀取指定路徑下的Person.class文件,如果該類有直接父類改淑,先加載Person的父類碍岔,再加載Person進(jìn)內(nèi)存;
2朵夏、在堆內(nèi)存中開辟空間蔼啦,分配地址;
3仰猖、在堆的對象空間中捏肢,對對象中的屬性進(jìn)行默認(rèn)初始化奈籽;
4、調(diào)用對應(yīng)的構(gòu)造函數(shù)進(jìn)行初始化鸵赫;
5衣屏、在構(gòu)造函數(shù)中,先調(diào)用父類的構(gòu)造函數(shù)進(jìn)行初始化辩棒;
6狼忱、父類初始化完畢后,再對子類的屬性進(jìn)行顯示初始化一睁;
7钻弄、構(gòu)造代碼塊初始化;
8者吁、進(jìn)行子類構(gòu)造函數(shù)的特定初始化窘俺;
9、初始化完畢后复凳,將地址值賦值給引用變量(不一定是在棧中批销,如下)。

class Demo
{
    Person p = new Person(); //在堆中
}

final關(guān)鍵字

  • final可以修飾類染坯,方法均芽,變量。
  • final修飾的類不可以被繼承单鹿。(繼承弊端:打破了封裝性掀宋。)
  • final修飾的方法不可以被覆蓋。(可以用于在父類中仲锄,若有幾個(gè)方法不希望被復(fù)寫時(shí))
  • final修飾的變量是一個(gè)常量劲妙,只能被賦值一次。(用于在類中值不會變化的儒喊,命名方式為所有字母大寫镣奋,單詞之間用下劃線連接;為什么要用final修飾變量怀愧,其實(shí)在程序中若一個(gè)數(shù)據(jù)是固定的侨颈,那么直接使用這個(gè)數(shù)據(jù)就可以了,但是這樣閱讀性差芯义,所以加上final)
  • 內(nèi)部類只能訪問被final修飾的局部變量哈垢。

Example1

class Person
{
    final int x;
}
class FinalDemo
{
    public static void main(String[] args){
        new Person();
    }
}

編譯錯(cuò)誤:可能尚未初始化變量x(指的顯示初始化)。
注意:變量若是有final修飾符扛拨,則一般都為靜態(tài):static final int x = 7耘分,每個(gè)對象的值都一樣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市求泰,隨后出現(xiàn)的幾起案子央渣,更是在濱河造成了極大的恐慌,老刑警劉巖渴频,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芽丹,死亡現(xiàn)場離奇詭異,居然都是意外死亡枉氮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門暖庄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來聊替,“玉大人,你說我怎么就攤上這事培廓∪乔模” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵肩钠,是天一觀的道長泣港。 經(jīng)常有香客問我,道長价匠,這世上最難降的妖魔是什么当纱? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮踩窖,結(jié)果婚禮上坡氯,老公的妹妹穿的比我還像新娘。我一直安慰自己洋腮,他們只是感情好箫柳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著啥供,像睡著了一般悯恍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伙狐,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天涮毫,我揣著相機(jī)與錄音,去河邊找鬼贷屎。 笑死窒百,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的豫尽。 我是一名探鬼主播篙梢,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼美旧!你這毒婦竟也來了渤滞?” 一聲冷哼從身側(cè)響起贬墩,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妄呕,沒想到半個(gè)月后陶舞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绪励,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年肿孵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疏魏。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡停做,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出大莫,到底是詐尸還是另有隱情蛉腌,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布只厘,位于F島的核電站烙丛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏羔味。R本人自食惡果不足惜河咽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赋元。 院中可真熱鬧库北,春花似錦、人聲如沸们陆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坪仇。三九已至杂腰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間椅文,已是汗流浹背喂很。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留皆刺,地道東北人少辣。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像羡蛾,于是被迫代替她去往敵國和親漓帅。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容