最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java基礎(chǔ)教程之繼承詳解

 更新時(shí)間:2014年08月31日 17:21:06   投稿:junjie  
這篇文章主要介紹了Java基礎(chǔ)教程之繼承詳解,繼承是除組合(composition)之外,提高代碼重復(fù)可用性(reusibility)的另一種重要方式,本文對(duì)繼承做了詳細(xì)講解,需要的朋友可以參考下

繼承(inheritance)是面向?qū)ο蟮闹匾拍睢@^承是除組合(composition)之外,提高代碼重復(fù)可用性(reusibility)的另一種重要方式。我們?cè)?a target="_blank" href="http://m.fzitv.net/article/54551.htm">組合(composition)中看到,組合是重復(fù)調(diào)用對(duì)象的功能接口。我們將看到,繼承可以重復(fù)利用已有的類(lèi)的定義。

類(lèi)的繼承

我們之前定義類(lèi)的時(shí)候,都是從頭開(kāi)始,詳細(xì)的定義該類(lèi)的每一個(gè)成員。比如下面的Human類(lèi):

復(fù)制代碼 代碼如下:

class Human
{  
   /**
     * accessor
     */
    public int getHeight()
    {
       return this.height;
    }

    /**
     * mutator
     */
    public void growHeight(int h)
    {
        this.height = this.height + h;
    }

    /**
     * breath
     */
    public void breath()
    {
        System.out.println("hu...hu...");
    }

    private int height;
}

從上面的類(lèi)定義,我們可以了解該類(lèi)的所有細(xì)節(jié): 該類(lèi)的數(shù)據(jù)成員,該類(lèi)的方法,該類(lèi)的接口。

現(xiàn)在要定義一個(gè)新的類(lèi),比如Woman類(lèi),并假設(shè)Woman與Human類(lèi)相當(dāng)類(lèi)似:


Human & Woman

我們可以像以前一樣,從頭開(kāi)始,完整的定義Woman類(lèi):

復(fù)制代碼 代碼如下:

class Woman
{
    /**
     * accessor
     */
    public int getHeight()
    {
       return this.height;
    }

    /**
     * mutator
     */
    public void growHeight(int h)
    {
        this.height = this.height + h;
    }


    /**
     * breath
     */
    public void breath()
    {
        System.out.println("hu...hu...");
    }

    /**
     * new method
     */
    public Human giveBirth()
    {
        System.out.println("Give birth");
        return (new Human(20));
    }

    private int height;
}

一個(gè)程序員在寫(xiě)上面程序的時(shí)候,會(huì)有很大的煩惱。許多定義都曾在Human類(lèi)中寫(xiě)過(guò),但我們還要重新敲一遍。Woman類(lèi)只新增了一個(gè)giveBirth()方法 (該方法創(chuàng)建并返回一個(gè)新的Human對(duì)象)。

利用繼承,我們可以避免上面的重復(fù)。讓W(xué)oman類(lèi)繼承自Human類(lèi),Woman類(lèi)就自動(dòng)擁有了Human類(lèi)中所有public成員的功能。

我們用extends關(guān)鍵字表示繼承:

復(fù)制代碼 代碼如下:

class Woman extends Human
{
    /**
     * new method
     */
    public Human giveBirth()
    {
        System.out.println("Give birth");
        return (new Human(20));
    }
}

這樣,我們就省去了大量的輸入。通過(guò)繼承,我們創(chuàng)建了一個(gè)新類(lèi),叫做衍生類(lèi)(derived class)。被繼承的類(lèi)(Human)稱(chēng)為基類(lèi)(base class)。衍生類(lèi)以基類(lèi)作為自己定義的基礎(chǔ),并補(bǔ)充基類(lèi)中沒(méi)有定義的giveBirth()方法。繼承關(guān)系可以表示為:

繼承: 箭頭指向基類(lèi)

可以用以下Test類(lèi)測(cè)試:

復(fù)制代碼 代碼如下:

public class Test
{
    public static void main(String[] args)
    {
        Woman aWoman = new Woman();
        aWoman.growHeight(120);
        System.out.println(aWoman.getHeight());                                            
    }
}

衍生層

通過(guò)繼承,我們創(chuàng)建了Woman類(lèi)。整個(gè)過(guò)程可以分為三個(gè)層次: 基類(lèi)定義,衍生類(lèi)定義,外部使用。

基類(lèi)定義的層次就是正常的定義一個(gè)類(lèi),比如上面的Human類(lèi)定義。

在外部使用者看來(lái)(比如Test類(lèi)中創(chuàng)建Woman類(lèi)對(duì)象),衍生類(lèi)有一個(gè)統(tǒng)一的外部接口:

對(duì)于外部使用者來(lái)說(shuō),上述接口就已經(jīng)足夠了。僅從接口看,衍生類(lèi)也沒(méi)有什么特別之處。

 然而,當(dāng)程序員在衍生類(lèi)定義的層次時(shí),就必須要小心:

首先,接口是混合的: getHeight()方法和growHeight()方法來(lái)自基類(lèi),giveBirth()方法則是在衍生類(lèi)內(nèi)部定義的。

還有更加復(fù)雜的地方。我們之前在類(lèi)的內(nèi)部可以自由訪問(wèn)類(lèi)的成員(利用this指代對(duì)象)。然而,當(dāng)我們?cè)赪oman類(lèi)的定義范圍內(nèi),我們無(wú)法訪問(wèn)基類(lèi)Human的private成員。我們記得private的含義: private的成員僅供該類(lèi)內(nèi)部使用。Woman類(lèi)是一個(gè)不同于Human類(lèi)的新類(lèi),所以位于Human類(lèi)的外部。在衍生類(lèi)中,不能訪問(wèn)基類(lèi)的private成員。

但有趣的是,我們的growHeight()和getHeight()方法依然可以運(yùn)行。這說(shuō)明基類(lèi)的private成員存在,我們只是不能直接訪問(wèn)。

為了清晰概念,我們需要了解衍生類(lèi)對(duì)象的生成機(jī)制。當(dāng)我們創(chuàng)建一個(gè)衍生類(lèi)的對(duì)象時(shí),Java實(shí)際上先創(chuàng)建了一個(gè)基類(lèi)對(duì)象(subobject),并在基類(lèi)對(duì)象的外部(注意,這里是基類(lèi)對(duì)象的外部,衍生類(lèi)對(duì)象的內(nèi)部),增加衍生類(lèi)定義的其他成員,構(gòu)成一個(gè)衍生類(lèi)對(duì)象。外部使用者能看到的,就是基類(lèi)和衍生類(lèi)的public成員。如下圖:

基類(lèi)對(duì)象與衍生類(lèi)對(duì)象

圖中黃色為基類(lèi)對(duì)象。基層的成員之間可以互相訪問(wèn) (利用Human類(lèi)定義中的this指代基類(lèi)對(duì)象)。

藍(lán)色部分為衍生對(duì)象新增的內(nèi)容,我將這部分稱(chēng)為衍生層。藍(lán)色和黃色部分共同構(gòu)成衍生對(duì)象。衍生層的成員可以相互訪問(wèn)(Woman定義中的this)。更進(jìn)一步,我們還可以訪問(wèn)基層中public的成員。為此,我們用super關(guān)鍵字來(lái)指代基類(lèi)對(duì)象,使用super.member的方式來(lái)表示基層的(public)成員。

當(dāng)我們位于衍生層時(shí)(也就是在定義Woman類(lèi)時(shí)),不能訪問(wèn)紅色的基層private成員。當(dāng)我們位于外部時(shí),既不能訪問(wèn)紫色的衍生層private成員,也不能訪問(wèn)紅色的基層private成員。

(衍生層的private成員有訪問(wèn)禁忌,所以標(biāo)為斜線?;鶎拥膒rivate成員訪問(wèn)禁忌最多,所以標(biāo)為交叉斜線)

super和this類(lèi)似,也是隱式參數(shù)。我們?cè)陬?lèi)定義的不同層次時(shí),this會(huì)有不同的含義。要小心的使用this和super關(guān)鍵字。

(Java并不強(qiáng)制使用this和super。Java在許多情況下可以自動(dòng)識(shí)別成員的歸屬。但我覺(jué)得這是個(gè)好習(xí)慣。)

protected

我們之前介紹了兩個(gè)訪問(wèn)權(quán)限相關(guān)的關(guān)鍵字,private和public,它們控制了成員的外部可見(jiàn)性。現(xiàn)在,我們介紹一個(gè)新的訪問(wèn)權(quán)限關(guān)鍵字: protected。

標(biāo)為protected的成員在該類(lèi)及其衍生類(lèi)中可見(jiàn)。這個(gè)概念很容易理解,就是說(shuō),基類(lèi)的protected成員可以被衍生層訪問(wèn),但不能被外部訪問(wèn),如下圖:

方法覆蓋

衍生類(lèi)對(duì)象的外部接口最終由基類(lèi)對(duì)象的public成員和衍生層的public成員共同構(gòu)成。如果基類(lèi)public成員和衍生層的public成員同名,Java接口中呈現(xiàn)的究竟是哪一個(gè)呢?

我們?cè)?a target="_blank" href="http://m.fzitv.net/article/54548.htm">構(gòu)造方法與方法重載中已經(jīng)提到,Java是同時(shí)通過(guò)方法名和參數(shù)列表來(lái)判斷所要調(diào)用的方法的。方法是由方法名和參數(shù)列表共同決定的。上述問(wèn)題中,如果只是方法名相同,而參數(shù)列表不同,那么兩個(gè)方法會(huì)同時(shí)呈現(xiàn)到接口,不會(huì)給我們?cè)斐衫_。外部調(diào)用時(shí),Java會(huì)根據(jù)提供的參數(shù),來(lái)決定使用哪個(gè)方法 (方法重載)。

如果方法名和參數(shù)列表都相同呢? 在衍生層時(shí),我們還可以通過(guò)super和this來(lái)確定是哪一個(gè)方法。而在外部時(shí),我們呈現(xiàn)的只是統(tǒng)一接口,所以無(wú)法同時(shí)提供兩個(gè)方法。這種情況下,Java會(huì)呈現(xiàn)衍生層的方法,而不是基層的方法。

這種機(jī)制叫做方法覆蓋(method overriding)。方法覆蓋可以被很好的利用,用于修改基類(lèi)成員的方法。比如,在衍生層,也就是定義Woman時(shí),可以修改基類(lèi)提供的breath()方法:

復(fù)制代碼 代碼如下:

class Woman extends Human
{/**
     * new method
     */
    public Human giveBirth()
    {
        System.out.println("Give birth");
        return (new Human(20));
    }

    /**
     * override Human.breath()
     */
    public void breath()
    {
        super.breath();
        System.out.println("su...");
    }
}

注意,此時(shí)我們位于衍生層,依然可以通過(guò)super來(lái)調(diào)用基類(lèi)對(duì)象的breath()方法。當(dāng)我們外部調(diào)用Woman類(lèi)時(shí),由于方法覆蓋,就無(wú)法再調(diào)用基類(lèi)對(duì)象的該方法了。

方法覆蓋保持了基類(lèi)對(duì)象的接口,而采用了衍生層的實(shí)現(xiàn)。

構(gòu)造方法

在了解了基類(lèi)對(duì)象和衍生層的概念之后,衍生類(lèi)的構(gòu)造方法也比較容易理解。

我們要在衍生類(lèi)的定義中定義與類(lèi)同名的構(gòu)造方法。在該構(gòu)造方法中:

1.由于在創(chuàng)建衍生對(duì)象的時(shí)候,基類(lèi)對(duì)象先被創(chuàng)建和初始化,所以,基類(lèi)的構(gòu)造方法應(yīng)該先被調(diào)用。我們可以使用super(argument list)的語(yǔ)句,來(lái)調(diào)用基類(lèi)的構(gòu)造方法。

2.基類(lèi)對(duì)象創(chuàng)建之后,開(kāi)始構(gòu)建衍生層 (初始化衍生層成員)。這和一般的構(gòu)建方法相同,參考構(gòu)造方法與方法重載

比如下面的程序中,Human類(lèi)有一個(gè)構(gòu)造方法:

復(fù)制代碼 代碼如下:

class Human
{  

    /**
     * constructor
     */
    public Human(int h)
    {
        this.height = h;
    }

    /**
     * accessor
     */
    public int getHeight()
    {
       return this.height;
    }

    /**
     * mutator
     */
    public void growHeight(int h)
    {
        this.height = this.height + h;
    }

    /**
     * breath
     */
    public void breath()
    {
        System.out.println("hu...hu...");
    }

    private int height;
}

衍生類(lèi)Woman類(lèi)的定義及其構(gòu)造方法:

復(fù)制代碼 代碼如下:

class Woman extends Human
{
    /**
     * constructor
     */
    public Woman(int h)
    {
        super(h); // base class constructor
        System.out.println("Hello, Pandora!");
    }

    /**
     * new method
     */
    public Human giveBirth()
    {
        System.out.println("Give birth");
        return (new Human(20));
    }

    /**
     * override Human.breath()
     */
    public void breath()
    {
        super.breath();
        System.out.println("su...");
    }
}

總結(jié)

extends

method overriding

protected

super.member, super()

相關(guān)文章

  • 詳解Java快速上手用戶后臺(tái)管理系統(tǒng)

    詳解Java快速上手用戶后臺(tái)管理系統(tǒng)

    只有在實(shí)戰(zhàn)中練習(xí)才能真正獲得能力的提升,本篇文章手把手帶你用Java快速上手實(shí)現(xiàn)一個(gè)用戶后臺(tái)管理系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2022-01-01
  • java并發(fā)分段鎖實(shí)踐代碼

    java并發(fā)分段鎖實(shí)踐代碼

    這篇文章主要介紹了java并發(fā)分段鎖實(shí)踐代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Java特性隊(duì)列和棧的堵塞原理解析

    Java特性隊(duì)列和棧的堵塞原理解析

    這篇文章主要介紹了Java特性隊(duì)列和棧的堵塞原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Spring中的Actuator使用詳解

    Spring中的Actuator使用詳解

    這篇文章主要介紹了Spring中的Actuator使用詳解,在生產(chǎn)環(huán)境中運(yùn)行的程序,并不總是穩(wěn)定、安靜、正確的,往往會(huì)遇到各式各樣的現(xiàn)場(chǎng)狀況,這個(gè)時(shí)候,就需要獲取該程序足夠多的運(yùn)行狀態(tài)信息,然后分析并對(duì)其進(jìn)行有效管理,需要的朋友可以參考下
    2023-09-09
  • Spring中@RequestParam使用及遇到的一些坑

    Spring中@RequestParam使用及遇到的一些坑

    @RequestParam 主要用于將請(qǐng)求參數(shù)區(qū)域的數(shù)據(jù)映射到控制層方法的參數(shù)上,下面這篇文章主要給大家介紹了關(guān)于Spring中@RequestParam使用及遇到的一些坑,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Java StringBuilder和StringBuffer源碼分析

    Java StringBuilder和StringBuffer源碼分析

    這篇文章主要針對(duì)Java中兩個(gè)常用的操作字符串的類(lèi) StringBuilder和StringBuffer進(jìn)行源碼分析,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Kotlin與Java 泛型缺陷和應(yīng)用場(chǎng)景詳解

    Kotlin與Java 泛型缺陷和應(yīng)用場(chǎng)景詳解

    這篇文章主要為大家介紹了Kotlin與Java 泛型缺陷和應(yīng)用場(chǎng)景詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Scala中如何中斷循環(huán)詳解

    Scala中如何中斷循環(huán)詳解

    在Scala中,可以使用break和continue語(yǔ)句來(lái)中斷循環(huán)。break語(yǔ)句可以在滿足某個(gè)條件時(shí)中斷循環(huán),而continue語(yǔ)句可以在滿足某個(gè)條件時(shí)跳過(guò)當(dāng)前循環(huán)迭代,直接執(zhí)行下一次迭代
    2023-04-04
  • SpringBoot Session共享實(shí)現(xiàn)圖解

    SpringBoot Session共享實(shí)現(xiàn)圖解

    這篇文章主要介紹了SpringBoot Session共享實(shí)現(xiàn)圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Java基于正則表達(dá)式實(shí)現(xiàn)查找匹配的文本功能【經(jīng)典實(shí)例】

    Java基于正則表達(dá)式實(shí)現(xiàn)查找匹配的文本功能【經(jīng)典實(shí)例】

    這篇文章主要介紹了Java基于正則表達(dá)式實(shí)現(xiàn)查找匹配的文本功能,結(jié)合具體實(shí)例形式分析了java正則查找、字符串遍歷、group分組相關(guān)操作技巧,需要的朋友可以參考下
    2017-04-04

最新評(píng)論

客服| 民勤县| 房产| 金溪县| 仙桃市| 泸水县| 垣曲县| 溧水县| 长岭县| 三河市| 仙居县| 柏乡县| 曲水县| 望城县| 肥城市| 永嘉县| 勃利县| 皮山县| 宁远县| 和顺县| 伊通| 永靖县| 平塘县| 铜鼓县| 塘沽区| 南江县| 开鲁县| 万盛区| 唐山市| 闽侯县| 彭山县| 南靖县| 金川县| 松桃| 合山市| 柳河县| 崇阳县| 比如县| 伊宁县| 淮安市| 濮阳县|