成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【從基礎(chǔ)學(xué) Java】繼承

Dongjie_Liu / 1328人閱讀

摘要:快速了解繼承在的繼承關(guān)系里子類(lèi)可以從獲取父類(lèi)的所有的公共和受保護(hù)成員字段方法和內(nèi)部類(lèi)。阻止繼承有些情況下,我們可能不希望子類(lèi)覆蓋父類(lèi)的方法,這時(shí)候,用關(guān)鍵字修飾方法即可實(shí)現(xiàn)該目的。

和現(xiàn)實(shí)世界中:子女可以繼承父母的一些特征(如:基因)、財(cái)產(chǎn)等一樣。OOP 中也有提供類(lèi)似的特性,一個(gè)類(lèi)完全可以從其它類(lèi)里獲得一些屬性和方法,而不需要我們自己重新定義。這種特性簡(jiǎn)單但強(qiáng)大 (Simple and powerful)。

快速了解繼承

在 Java 的繼承關(guān)系里:子類(lèi)可以從獲取父類(lèi)的所有的公共和受保護(hù)成員(字段、方法和內(nèi)部類(lèi))。當(dāng)然,構(gòu)造方法不是成員 (members) ,所以不能被繼承。同時(shí),在 Java 的繼承里,子類(lèi)可以做如下事情:

直接使用繼承來(lái)的字段

直接使用繼承來(lái)的方法

聲明和父類(lèi)同名字段,隱藏 掉父類(lèi)字段

通過(guò)父類(lèi)提供的公有/受保護(hù)的方法訪問(wèn)父類(lèi)的私有成

創(chuàng)建新的字段

重寫(xiě)父類(lèi)同方法簽名的實(shí)例方法,隱藏 掉父類(lèi)方法

重寫(xiě)父類(lèi)同方法簽名的靜態(tài)方法,隱藏 掉父類(lèi)方法

編寫(xiě)父類(lèi)中不存在的方法

使用 super 關(guān)鍵字,利用父類(lèi)構(gòu)造方法

覆蓋

當(dāng)子類(lèi)擁有和父類(lèi)(或接口)同樣方法簽名的方法,這種現(xiàn)象叫做覆蓋。如以下代碼:

class Father
{
    public void doSomthing(){
        // Father do something
    }
}

class Son extends Father{
    @Override
    public void doSomething(){
        // Son do something
    }
}

覆蓋父類(lèi)實(shí)例方法

覆蓋父類(lèi)靜態(tài)方法

覆蓋接口默認(rèn)方法 (JDK 8+)

對(duì)于實(shí)例方法的覆蓋,實(shí)際是子類(lèi)擁有自己的方法。
對(duì)于靜態(tài)方法的覆蓋,要記?。红o態(tài)方法時(shí)屬于類(lèi)的,在多態(tài)中,調(diào)用的始終是類(lèi)的方法。接口里的靜態(tài)方法永遠(yuǎn)不會(huì)被覆蓋。

    Father father = new Son();
    Father.staticMethod(); // 這里使用的是父類(lèi)Father的靜態(tài)方法

對(duì)于接口方法的覆蓋,遵循以下原則:
1.實(shí)例方法的優(yōu)先級(jí)大于接口方法 (JDK8+)

interface Animal{
    default void saySomething(){
        // Animal say something
    }
}
interface Cow extends Animal{
    default void saySomething(){
        // Cow say something
    }
}

class MyCow implements Cow{
    @Override
    public void saySomething(){
        // MyCow say something
    }
    
    Animal myCow = new MyCow();
    myCow.saySomething(); // MyCow say something
}

2.有共同祖先的接口,先被覆蓋的方法(繼承深度低)會(huì)被后覆蓋的方法(繼承級(jí)別高)覆蓋

interface Animal{
    default void saySomething(){
        // Animal say something
    }
}
interface Pig extends Animal{
    default void saySomething(){
        // Pig say something
    }
}
interface BigPig extends Pig{
    default void saySomething(){
        // BigPig say something
    }
}
class MyPig implements Pig, BigPig{
    public static void main(String...args){
        MyPig myPig = new MyPig();
        myPig.saySomething(); // BigPig saySomething()
    }
}

P.S. 如果出現(xiàn)同一繼承級(jí)別(上例中 BigPig 和 Pig 都繼承 Animal 接口)或者子類(lèi)繼承的接口無(wú)相關(guān)關(guān)系,但是接口間有同方法簽名的方法,就會(huì)出現(xiàn)覆蓋沖突。需要用 super 關(guān)鍵字指明具體實(shí)現(xiàn)哪個(gè)接口的方法或者直接覆蓋。

interface Run{
    default void run(){
        // Run run
    }
}

interface Car{
    default void run(){
        // Car run
    }
}

class MyCar implements Run, Car{
    @Override
    public void run(){
        Car.super.run();
    
    }
}

同時(shí),我們需要注意,Java 子類(lèi)覆蓋父類(lèi)方法,應(yīng)該:

方法的訪問(wèn)權(quán)限大于等于父類(lèi)

方法的返回值小于等于父類(lèi)

方法拋出的異常小余等于父類(lèi)

如果子類(lèi)定義和父類(lèi)同方法簽名的方法,會(huì)有如下結(jié)果:

x 父類(lèi)的實(shí)例方法 父類(lèi)的靜態(tài)方法
子類(lèi)的實(shí)例方法 覆蓋父類(lèi)方法 編譯錯(cuò)誤
子類(lèi)的靜態(tài)方法 編譯錯(cuò)誤 隱藏父類(lèi)方法
多態(tài)

我們已經(jīng)知道,子類(lèi)可以覆蓋父類(lèi)的方法。如果有一個(gè)類(lèi)繼承自另外一個(gè)類(lèi),我們完全可以用一個(gè)父類(lèi)來(lái)引用一個(gè)子類(lèi),如:

class Person{
    public void saySomething(){
        // Person say something
    }
}
class Father{
    @Override
    public void saySomething(){
        // Father say something
    }
}

class Test{
    pubilc static void main(String...args){
        Father father = new Father();
        Person person = father; // 父類(lèi)引用子類(lèi)對(duì)象
    }
}

像這種父類(lèi)引用子類(lèi)對(duì)象的現(xiàn)象,Java 里叫做多態(tài) (Polymorphism)。在 Java 里,只有滿足如下三個(gè)條件,才能叫多態(tài):

繼承關(guān)系

覆蓋方法

父類(lèi)引用子類(lèi)對(duì)象

對(duì)于多態(tài)方法的運(yùn)行,編譯器會(huì)列舉所有父類(lèi)和子類(lèi)符合調(diào)用方法簽名(方法名+參數(shù)列表)的方法,然后以以下原則編譯、調(diào)用方法:

成員變量(編譯和運(yùn)行都看左邊)

成員方法(編譯看左邊,運(yùn)行看右邊)

靜態(tài)方法(編譯和運(yùn)行都看左邊)

其中,調(diào)用 private, final, static 方法的過(guò)程叫靜態(tài)綁定,否則叫動(dòng)態(tài)綁定
在使用多態(tài)的過(guò)程中,最有效的判斷語(yǔ)句能否通過(guò)編譯的方法是:

右邊的類(lèi)是否是(IS-A)左邊的類(lèi)

如示例代碼里的 father(Father) IS-A Person。

阻止繼承

有些情況下,我們可能不希望子類(lèi)覆蓋父類(lèi)的方法,這時(shí)候,用 final 關(guān)鍵字修飾方法即可實(shí)現(xiàn)該目的。編譯器可以對(duì)用final的方法進(jìn)行內(nèi)聯(lián)操作優(yōu)化處理。

強(qiáng)制轉(zhuǎn)換

在多態(tài)里,我們知道一個(gè)父類(lèi)可以引用一個(gè)子類(lèi)對(duì)象:

Father father = new Son();

但是,反過(guò)來(lái)就不行了:

Son son = new Father();

如果需要讓編譯器不報(bào)錯(cuò),我們就得進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換操作:

Son son = (Son)new Father();

不過(guò),這么做有風(fēng)險(xiǎn),我們一般要使用 instanceof關(guān)鍵字先判斷,能否將父類(lèi)“安全”轉(zhuǎn)換成子類(lèi):

Father f = ...;
if (f instanceof Son){
    Son son = (Son)f;
}
抽象類(lèi)與接口

在繼承體系里,比較常用的就是抽象類(lèi)和接口。它們比較相似:

都能被繼承

都包含抽象方法

都不能被實(shí)例化

然而,它們還是有不同的,例如:

抽象類(lèi)可以聲明非 final&&static 的字段,接口不行(默認(rèn) public static final )

抽象類(lèi)可以有構(gòu)造方法,接口不行

抽象類(lèi)可以聲明非 public 方法,接口不行(默認(rèn)方法是 public )

一個(gè)類(lèi)只能繼承一個(gè)抽象類(lèi),可以繼承多個(gè)接口

然后,抽象類(lèi)和接口有不同的使用場(chǎng)景:P
抽象類(lèi):

在相關(guān)類(lèi)里共享代碼

規(guī)定了一系列通用的方法和屬性

需要定義非靜態(tài)、非共有的方法

接口:

定義屬性,如可比較 (Comparable)、可飛(Flyable)

定義行為,不關(guān)心具體實(shí)現(xiàn)

希望使用多繼承

繼承的技巧

在 Java 里,我們一般按照如下規(guī)則使用繼承:

將公共操作放在超類(lèi)(父類(lèi))中

不要使用受保護(hù)的域

繼承嚴(yán)格遵循 is-a 原則

不要過(guò)多得使用反射

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66789.html

相關(guān)文章

  • Java基礎(chǔ)(了解繼承

    摘要:上學(xué)學(xué)的完全沒(méi)印象,基礎(chǔ)爛的不行,最近項(xiàng)目主要是改,有時(shí)間就看了一下這本書(shū)補(bǔ)一下基礎(chǔ)在寫(xiě)項(xiàng)目時(shí),老用到繼承,但是對(duì)其了解不深,會(huì)用但是不理解概念繼承是面向?qū)ο缶幊碳夹g(shù)的一塊基石,因?yàn)樗试S創(chuàng)建分等級(jí)層次的類(lèi)。 上學(xué)學(xué)的完全沒(méi)印象,Java基礎(chǔ)爛的不行,最近項(xiàng)目主要是改bug,有時(shí)間就看了一下Head First Java這本書(shū)補(bǔ)一下基礎(chǔ) 在寫(xiě)項(xiàng)目時(shí),老用到Java繼承,但是對(duì)其了解不深...

    MageekChiu 評(píng)論0 收藏0
  • 基礎(chǔ)學(xué) Java】序

    摘要:本人生性愚鈍,在大學(xué)期間沒(méi)能好好領(lǐng)略等面向?qū)ο缶幊痰镊攘Α,F(xiàn)借助一些較為權(quán)威的書(shū)籍資料,將基礎(chǔ)知識(shí)里比較重要的東西整理成文,命名從基礎(chǔ)學(xué)。如果博文不慎侵犯了您的著作權(quán),請(qǐng)聯(lián)系我。 和很多大學(xué)一樣,我的學(xué)校也是從 Java 、C++ 入手,教給我們面向?qū)ο?(OOP) 的思想。本人生性愚鈍,在大學(xué)期間沒(méi)能好好領(lǐng)略 Java 等面向?qū)ο缶幊痰镊攘Α,F(xiàn)借助一些較為權(quán)威的書(shū)籍資料,將 Java...

    JackJiang 評(píng)論0 收藏0
  • 先轉(zhuǎn)行基礎(chǔ)入門(mén)學(xué)編程可以嗎?

    摘要:你只需要相信一句話鍵盤(pán)敲爛,月薪過(guò)萬(wàn)就行了,進(jìn)入正文,零基礎(chǔ)入門(mén)知識(shí)點(diǎn)大綱如下其實(shí)到目前為止,的崗位需求還是非常多的,還是大多數(shù)企業(yè)后臺(tái)開(kāi)發(fā)的主流編程語(yǔ)言,功能強(qiáng)大,還是很值得學(xué)習(xí)的。 ...

    desdik 評(píng)論0 收藏0
  • 學(xué) JAVA 的幾點(diǎn)建議

    摘要:自制力好的人,估計(jì)在保存后會(huì)翻出來(lái)看兩眼,過(guò)幾天又忘得一干二凈了。多思考學(xué)會(huì)思考,養(yǎng)成多思考的習(xí)慣。以項(xiàng)目來(lái)驅(qū)動(dòng)自己學(xué)習(xí),整個(gè)過(guò)程將會(huì)有趣得多。后語(yǔ)以上就是我對(duì)自學(xué)的幾點(diǎn)建議,希望對(duì)你們有幫助。 微信公眾號(hào):一個(gè)優(yōu)秀的廢人如有問(wèn)題或建議,請(qǐng)后臺(tái)留言,我會(huì)盡力解決你的問(wèn)題。 showImg(https://segmentfault.com/img/remote/1460000018208...

    klinson 評(píng)論0 收藏0
  • 基礎(chǔ)學(xué) Java】泛型

    摘要:泛型方法泛型類(lèi)中可以定義靜態(tài)非靜態(tài)的泛型方法。上述泛型類(lèi)會(huì)被替換成下面形式一般使用第一個(gè)限定類(lèi)型替換變?yōu)樵碱?lèi)型,沒(méi)有限定類(lèi)型,使用替換。 引言 在面向?qū)ο蟮氖澜缋铮覀內(nèi)绻枰粋€(gè)容器來(lái)盛裝對(duì)象。舉個(gè)例子:一個(gè)籃子。我們可以用這個(gè)籃子裝蘋(píng)果,也可以用這個(gè)籃子裝香蕉?;?OOP 的思想,我們不希望為蘋(píng)果和香蕉分別創(chuàng)建不同的籃子;同時(shí),我們希望放進(jìn)籃子里的是蘋(píng)果,拿出來(lái)的還是蘋(píng)果。于是...

    huhud 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<