05- 繼承與多態(tài)

一. 繼承

  • 面向?qū)ο笕筇卣鳎悍庋b楼眷、繼承敞葛、多態(tài)
  • 繼承是多態(tài)的前提:沒有繼承坏逢,就沒有多態(tài)
  • 繼承主要解決的問題:共性抽取
  • 繼承的體現(xiàn):extends淤袜、implements
  • 子類擁有父類的內(nèi)容,也擁有自己專有的內(nèi)容稚铣;子類也可以當作一個父類
  • 代碼中的格式:
  • 父類的定義:一個普通的類定義
  • 子類的定義:public class 子類名稱 extends 父類名稱{}

1. 對成員變量的影響

  • 父類和子類的成員變量重名時箱叁,有兩種訪問方式:

  • 直接通過子類對象訪問成員變量

    • 等號左邊是誰,就優(yōu)先用誰榛泛,沒有則向上找
  • 間接通過成員方法訪問成員變量

    • 方法屬于誰蝌蹂,就優(yōu)先用誰
  • 區(qū)分局部變量噩斟、父類成員變量曹锨、本類成員變量重名的方法:thissuper關(guān)鍵字

  • 局部變量:直接寫變量名

  • 本類的成員變量:this.成員變量名

  • 父類的成員變量名:super.成員變量名

2. 對成員方法的影響

  • 成員方法重名:

  • 在繼承關(guān)系中剃允,方法的名稱一樣沛简,參數(shù)列表也一樣-----------重寫(Override)、也叫覆蓋

  • 創(chuàng)建的是子類對象斥废,則優(yōu)先使用子類的方法

  • 方法覆蓋注意事項:

  • IDEA中寫上@Override注解可以來檢測是否是方法覆蓋--------安全檢測手段(推薦)

  • 子類方法的返回值必須小于等于父類方法的返回值范圍

  • 子類方法的權(quán)限必須大于等于父類方法的權(quán)限修飾符椒楣。

public > protected > (default) > private 注:defualt不是關(guān)鍵字,表示留空

3. 對構(gòu)造方法的影響

  • 繼承關(guān)系時牡肉,父子類構(gòu)造方法的訪問特點:

  • 子類必須調(diào)用父類構(gòu)造方法捧灰,不寫則贈送super()(子類構(gòu)造方法中默認隱含的super()調(diào)用)----> 先執(zhí)行父類構(gòu)造方法

  • 只有子類構(gòu)造方法,才能調(diào)用父類構(gòu)造方法

  • 子類構(gòu)造可以通過super關(guān)鍵字調(diào)用父類重載構(gòu)造方法

  • super的父類構(gòu)造調(diào)用统锤,必須是子類構(gòu)造方法的第一個語句毛俏,也是唯一一個

4. super關(guān)鍵字典型應(yīng)用

  • 在子類的成員方法中,訪問父類的成員變量
  • 在子類的成員方法中饲窿,訪問父類的成員方法
  • 在子類的構(gòu)造方法中煌寇,訪問父類的構(gòu)造方法

5. this關(guān)鍵字的典型應(yīng)用

  • 在本類的成員方法中,訪問本類的成員變量
  • 在本類的成員方法中逾雄,訪問本類的另一個成員方法
  • 在本類的構(gòu)造方法中阀溶,訪問本類的另一個構(gòu)造方法
    • this(…)調(diào)用也必須是構(gòu)造方法的第一個語句,也是唯一一個
    • superthis兩種構(gòu)造調(diào)用鸦泳,不能同時使用

6. super/this內(nèi)存示意圖

03-super與this的內(nèi)存圖.png

7. 繼承的特性

  • Java中的繼承是單繼承的:一個類的直接父類只能用唯一一個

  • Java中可以多級繼承

  • 一個父類可以有很多子類

二. 抽象類

  • 抽象方法:父類中不確定具體如何實現(xiàn)的方法-------> 抽象方法

  • 抽象類:包含抽象方法的類-----抽象方法所在的類银锻,必須是抽象類

  • 格式:

  • 加上abstract關(guān)鍵字,去掉大括號做鹰,沒有方法體

    • public abstract void eat();
  • 如何使用抽象方法击纬、抽象類:

  • 不能直接創(chuàng)建new抽象類對象

  • 必須用一個子類來繼承抽象父類

  • 子類必須覆蓋重寫(實現(xiàn))抽象類中的所有抽象方法----去掉abstract關(guān)鍵字----IDEA中快捷鍵alt+Insert

  • 創(chuàng)建子類對象進行使用

三. 接口

  • 接口就是多個類的公共的規(guī)范標準

  • 接口是一種引用類型,最重要的內(nèi)容就是其中的抽象方法

  • 定義接口的格式:

public interface 接口名稱{
    //接口內(nèi)容
}
  • 如果是Java 7誊垢,接口內(nèi)容中可以包含:常量掉弛、抽象方法
  • 如果是Java 8+症见,還可以額外包含:默認方法、靜態(tài)方法
  • 如果是Java 9+殃饿,還可以額外包含:私有方法
- 接口中的抽象方法谋作,修飾符必須是兩個固定的關(guān)鍵字:public abstract
- 這兩個關(guān)鍵字,可以選擇性省略(初學(xué)不推薦)
  • 接口使用步驟:

  • 不能直接使用乎芳,必須有一個實現(xiàn)類來實現(xiàn)接口

    • public class 實現(xiàn)類名稱 implements 接口名{}
  • 接口的實現(xiàn)類必須覆蓋重寫(實現(xiàn))接口中所有的抽象方法

  • 創(chuàng)建實現(xiàn)類的對象遵蚜,進行使用

接口包含--默認方法

  • 問題描述:

接口升級問題:接口中新增了一個抽象方法,那么在實現(xiàn)類中就必須要修改去實現(xiàn)新增的抽象方法

  • 解決方案:

新添加的方法--->定義成默認方法--->實現(xiàn)類中不用覆蓋重寫

public default 返回值類型 方法名稱(參數(shù)列表){
    
}
  • 接口的默認方法奈惑,可以通過接口實現(xiàn)類對象吭净,直接調(diào)用
  • 接口的默認方法,也可以被接口實現(xiàn)類進行覆蓋重寫

接口包含--靜態(tài)方法

public static 返回值類型 方法名稱(參數(shù)列表){
    
}
  • 不能通過接口實現(xiàn)類的對象來調(diào)用接口中的靜態(tài)方法
  • 正確方法:通過接口名稱直接調(diào)用接口中的靜態(tài)方法

接口包含--私有方法

  • 問題描述:

抽取一個共有方法肴甸,解決兩個默認方法之間重復(fù)代碼的問題寂殉,但是這個公共方法不應(yīng)該讓實現(xiàn)類使用,應(yīng)該是私有化的

  • 解決方案:

  • 普通私有化方法:解決多個默認方法之間重復(fù)代碼問題

    • private 返回值類型 方法名稱(參數(shù)列表){}
  • 靜態(tài)私有方法:解決多個靜態(tài)方法之間重復(fù)代碼問題

    • private static 返回值類型 方法名稱(參數(shù)列表){}
  • 只有接口自己能調(diào)用

接口包含--成員變量

接口中也可以定義“成員變量”原在,但必須使用public static final三個關(guān)鍵字進行修飾,從效果上看友扰,其實就是接口的【常量】

  • 格式與注意事項:

  • public static final 數(shù)據(jù)類型 常量名稱 = 數(shù)據(jù)值;

  • public static final關(guān)鍵字可以省略不寫

  • 接口中的常量,必須進行賦值

  • 推薦:常量名稱完全大寫庶柿,并用下劃線進行分隔-----NUM_MONEY

注意事項

  • 接口不能有靜態(tài)代碼塊

  • 接口不能用構(gòu)造方法

  • 一個類的有且只有一個直接父類村怪,但是一個類可以同時實現(xiàn)多個接口----用逗號隔開

    • public class Interfaceimpl implements MyInterface1,MyInterface2{}
  • 如果實現(xiàn)類所實現(xiàn)的多個接口類中有重名的抽象方法,則只需要重寫覆蓋一遍

  • 如果實現(xiàn)類所實現(xiàn)的多個接口類中有重名的默認方法浮庐,那么實現(xiàn)類一定要對沖突的默認方法進行覆蓋重寫

  • 一個類的直接父類中的方法和接口當中的默認方法產(chǎn)生了沖突甚负,優(yōu)先使用父類當中的方法

類與接口的關(guān)系

  • 類與類之間是單繼承的,直接父類只有一個
  • 類與接口之間是多實現(xiàn)的审残,一個類可以實現(xiàn)多個接口梭域、
  • 接口與接口之間是多繼承的

四. 多態(tài)

  • extends繼承或者implements實現(xiàn),是多態(tài)性的前提

  • 對象的多態(tài)性:一個對象擁有多種形態(tài)

  • 代碼中體現(xiàn)多態(tài)性:

  • 父類引用指向子類對象

    • 父類名稱 對象名 = new 子類名稱(); 左父右子---子類被當作父類來看待(一只貓被當作動物看待)
    • 接口名稱 對象名 = new 實現(xiàn)類名稱();

成員變量的訪問規(guī)則

  • 直接通過對象名稱訪問:看等號左邊是誰维苔,就優(yōu)先用誰碰辅,沒有則向上(父類)找
  • 間接通過成員方法訪問:看該方法屬于誰,就優(yōu)先用誰介时,沒有則向上(父類)找
  • 口訣:編譯看左邊没宾,運行還看左邊

成員方法的訪問規(guī)則

  • new的是誰,就優(yōu)先用誰沸柔,沒有則向上(父類)找
  • 口訣:編譯看左邊循衰,運行看右邊
ublic class Demo03MultiMethod {
    public static void main(String[] args) {
        Fu obj = new Zi();
        obj.method();//父子都有,優(yōu)先用子
        obj.methodFu();//子類沒有褐澎,父類有,向上找父類
        //編譯看左邊会钝,左邊是Fu,F(xiàn)u中沒有methodZi()方法,所以編譯報錯
        //obj.methodZi();錯誤寫法
    }
}

多態(tài)的好處

04-使用多態(tài)的好處.png

五. 引用類型轉(zhuǎn)型

多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型和向下轉(zhuǎn)型

對象的向上轉(zhuǎn)型

  • 對象的向上轉(zhuǎn)型迁酸,其實就是多態(tài)寫法

  • 父類名稱 對象名 = new 子類名稱(); 子類被當作父類來看待(一只貓被當作動物看待)

  • 向上轉(zhuǎn)型一定是安全的:從小范圍轉(zhuǎn)向了大范圍

對象的向下轉(zhuǎn)型

  • 問題描述:

  • 向上轉(zhuǎn)型的弊端---對象一旦向上轉(zhuǎn)型為父類先鱼,就無法調(diào)用子類原本持有的內(nèi)容

  • 對象的向下轉(zhuǎn)型

  • 其實就是一個【還原】的動作

  • 格式:

  • 子類名稱 對象名 = (子類名稱)父類對象;

Animal animal = new Cat();//本來是貓,向上轉(zhuǎn)型為動物
Cat cat = (Cat) animal;//將本來已經(jīng)轉(zhuǎn)型為動物的貓奸鬓,還原成本來的貓
  • 注意事項:

  • 對象創(chuàng)建的時候必須保證本來就是貓

  • 類似于基本數(shù)據(jù)類型的強制轉(zhuǎn)換

六. instanceof關(guān)鍵字

  • 問題描述:

  • 如何知道一個父類引用的對象焙畔,本來是什么子類?(對象本來創(chuàng)建的時候是一只貓呢串远?)

  • 格式:

  • 對象名 instanceof 類名稱

  • 返回一個boolean結(jié)果宏多,判斷了前面的對象能不能當作后面類型的實例

七. 多態(tài)-接口的練習(xí)

06-筆記本電腦案例分析.png

Usb接口

package cn.arnold.day03.demo04;

public interface Usb {
    //開啟usb
    public void openUsb();

    //關(guān)閉usb
    public void closeUsb();
}

鼠標實現(xiàn)類

package cn.arnold.day03.demo04;

public class Mouse implements Usb {
    @Override
    public void openUsb() {
        System.out.println("打開鼠標usb");
    }

    @Override
    public void closeUsb() {
        System.out.println("關(guān)閉鼠標usb");
    }

    //鼠標點擊功能
    public void click() {
        System.out.println("鼠標點擊");
    }
}

鍵盤實現(xiàn)類

package cn.arnold.day03.demo04;

public class KeyBoard implements Usb {
    @Override
    public void openUsb() {
        System.out.println("打開鍵盤usb");
    }

    @Override
    public void closeUsb() {
        System.out.println("關(guān)閉鍵盤usb");
    }

    //鍵盤輸入功能
    public void type() {
        System.out.println("鍵盤輸入");
    }
}

電腦類

package cn.arnold.day03.demo04;

public class KeyBoard implements Usb {
    @Override
    public void openUsb() {
        System.out.println("打開鍵盤usb");
    }

    @Override
    public void closeUsb() {
        System.out.println("關(guān)閉鍵盤usb");
    }

    //鍵盤輸入功能
    public void type() {
        System.out.println("鍵盤輸入");
    }
}

主方法類

package cn.arnold.day03.demo04;

/*
描述筆記本類,實現(xiàn)筆記本使用鼠標澡罚、鍵盤
1.usb接口:包含開啟伸但、關(guān)閉功能
2.筆記本類:包含開機、關(guān)機留搔、使用usb設(shè)備功能
3.鼠標實現(xiàn)類:實現(xiàn)usb接口更胖、鼠標點擊功能
4.鍵盤實現(xiàn)類:實現(xiàn)usb接口、鍵盤輸入功能
 */
public class Main {
    public static void main(String[] args) {
        Computer com = new Computer();
        //開機
        com.powerOn();
        //使用鼠標usb設(shè)備
        Usb usb = new Mouse();//將鼠標向上轉(zhuǎn)型為Usb
        com.useUsbDevice(usb);
        //使用鍵盤設(shè)備
        com.useUsbDevice(new KeyBoard());//使用匿名對象催式,隱藏了keyboard向上轉(zhuǎn)型為Usb操作
        /*KeyBoard keyboard = new KeyBoard();
        com.useUsbDevice(keyboard);*/
        //關(guān)機
        com.powerOff();
    }
}

八. final關(guān)鍵字

  • 含義:

  • 最終的函喉、不可改變的

修飾一個類

  • 格式:修飾符 final class 類名稱{}

  • 含義:

    • 當前這個類不能有任何子類(太監(jiān)類)
    • 其中所有的成員方法都無法進行覆蓋重寫(因為沒兒子)

修飾一個方法

  • 格式:修飾符 final 返回值類型 方法名(參數(shù)列表){}
  • 含義:不能被覆蓋重寫

注意事項:

  • 對于類和方法來說,不能同時使用abstractfinal關(guān)鍵字-----互相矛盾

修飾一個局部變量

  • 格式:修飾符 final 變量類型 變量名 = 值 必須賦值
  • 含義:一次賦值荣月,終生不變

注意事項:

  • 對于基本數(shù)據(jù)類型,不可變的是數(shù)值---------只能賦值一次
  • 對于引用數(shù)據(jù)類型梳毙,不可變的是地址值 ----- 只能new一次

修飾成員變量

  • 格式:private final 變量類型 變量名
  • 含義:變量也是不可變的-----Setter方法失效

注意事項:

  • 由于成員變量有默認值哺窄,當使用final關(guān)鍵字后,編譯器將不再贈送默認值账锹,必須手動賦值
  • 要么直接賦值萌业,要么通過構(gòu)造方法賦值(二者選其一)
  • 通過構(gòu)造方法賦值必須保證所有重載形式的構(gòu)造方法都對這個變量賦值

九. 權(quán)限修飾符

public protected (default)省略不寫 private
同一類中 YES YES YES YES
同一個包 YES YES YES NO
不同包---子類 YES YES NO NO
不同包---非子類 YES NO NO NO

十. 內(nèi)部類

例如:身體和心臟(內(nèi)部類)的關(guān)系,心臟必須依賴于身體才有用

成員內(nèi)部類

  • 格式:
修飾符 class 外部類名稱 {
    修飾符 class 內(nèi)部類名稱 {
        //...
    }
    //...
}
  • 使用規(guī)則:

  • 內(nèi)用外奸柬,隨意訪問生年;外用內(nèi),需要內(nèi)部對象

  • 編譯后的.class文件信息:Body.class廓奕、Body$Heart.class

  • 如何使用成員內(nèi)部類:

  • 間接訪問:在外部類的方法中抱婉,使用內(nèi)部類,在main中只是調(diào)用外部類的方法

  • 直接訪問:外部類名稱.內(nèi)部類名稱 對象名稱 = new 外部類名稱().內(nèi)部類名稱();桌粉,在main中通過創(chuàng)建的對象

  • 內(nèi)部類蒸绩、外部類成員變量重名:

  • 外部類名稱.this.外部類成員變量名

局部內(nèi)部類(包含匿名內(nèi)部類)

  • 一個類定義在一個方法內(nèi)部------局部內(nèi)部類

  • 含義:只有當前所屬的方法才能使用它,出了這個方法就不能用了

  • 格式:

public 返回值 方法名(參數(shù)列表) {
    class 內(nèi)部類名稱 {
        //...
    }
    //...
}
  • 注意事項:

  • 局部內(nèi)部類铃肯,如果希望訪問方法的局部變量患亿,那么這個局部變量必須是【有效final的】

  • 原因:局部類對象(堆)的生命周期比局部變量(棧)長

內(nèi)部類的修飾符規(guī)則

  • 外部類:publi/(default)
  • 成員內(nèi)部類:public/protected/(default)/private
  • 局部內(nèi)部類:(default)

匿名內(nèi)部類(重點)

  • 問題描述:

  • 如果接口的實現(xiàn)類(或者是父類的子類)只需要使用唯一的一次,這種情況下就可以省略掉該類的定義押逼,改為使用匿名內(nèi)部類

  • 定義格式:直接new接口

接口名稱 對象名 = new 接口名稱(){
    //覆蓋重寫接口方法----匿名內(nèi)部類
};
  • 注意事項:接口名稱 對象名 = new 接口名稱(){...};

  • new代表創(chuàng)建的動作

  • 接口名稱就是匿名內(nèi)部類需要實現(xiàn)的那個接口

  • {...}才是匿名內(nèi)部類的內(nèi)容

  • 匿名內(nèi)部類步藕,在創(chuàng)建對象的時候惦界,只能使用唯一的一次------需要重復(fù)使用接口方法則不要用匿名內(nèi)部類

  • 匿名對象,在調(diào)用方法的時候咙冗,只能調(diào)用唯一的一次(一次只能調(diào)用一個方法)---new Student().studyCoding()

十一. 引用類型用法總結(jié)

基本類型可以作為成員變量表锻、作為方法的參數(shù)、作為方法的返回值乞娄,引用類型同樣可以-----String就是引用類型

class作為成員變量

interface作為成員變量

interface作為方法的參數(shù)和返回值

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞬逊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仪或,更是在濱河造成了極大的恐慌确镊,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異衷快,居然都是意外死亡信粮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門旨巷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人添忘,你說我怎么就攤上這事采呐。” “怎么了搁骑?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵斧吐,是天一觀的道長。 經(jīng)常有香客問我仲器,道長煤率,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任乏冀,我火速辦了婚禮蝶糯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辆沦。我一直安慰自己昼捍,他們只是感情好,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布众辨。 她就那樣靜靜地躺著端三,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鹃彻。 梳的紋絲不亂的頭發(fā)上郊闯,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音,去河邊找鬼团赁。 笑死育拨,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的欢摄。 我是一名探鬼主播熬丧,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼怀挠!你這毒婦竟也來了析蝴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤绿淋,失蹤者是張志新(化名)和其女友劉穎闷畸,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吞滞,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡佑菩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了裁赠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殿漠。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖佩捞,靈堂內(nèi)的尸體忽然破棺而出绞幌,到底是詐尸還是另有隱情,我是刑警寧澤失尖,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布啊奄,位于F島的核電站,受9級特大地震影響仪吧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜出皇,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望畏浆。 院中可真熱鬧刻获,春花似錦蝎毡、人聲如沸沐兵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽老充。三九已至,卻和暖如春巷嚣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留次酌,地道東北人和措。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓庄呈,卻偏偏與公主長得像派阱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子贫母,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

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