18.JAVA編程之多態(tài)性和instanceof關(guān)鍵字

多態(tài)是面向?qū)ο笕筇卣髦?/h1>

一、什么是多態(tài)

對象在運行過程中的多種形態(tài)

二、多態(tài)分類

1.方法的重載和重寫
2.對象的多態(tài)性
例如:用父類的引用指向子類對象(用大的類型去接受小的類型,向上轉(zhuǎn)型、自動轉(zhuǎn)換)
Chicken home= new HomeChicken();
結(jié)論:
在編程時針對抽象類型的編寫代碼,稱為面向抽象編程(或面向接口編程)
父類通常都定義為抽象類、接口

對象的多態(tài)性

對象多態(tài)性是從繼承關(guān)系中的多個類而來

向上轉(zhuǎn)型:將子類實例轉(zhuǎn)為父類引用

格式:父類 父類對象= 子類實例; 自動轉(zhuǎn)換
示例代碼:

public class Demo {

    public static void main(String[] args) {
        //用父類的引用指向子類對象(用大的類型來表示小的類型),自動轉(zhuǎn)換(向上轉(zhuǎn)型)
        Chicken hc = new HomeChicken("小米");
       // hc.eat();
        YeChicken yc = new YeChicken("大米");
       // yc.eat();

       // hc=yc;
      //  hc.eat();
        eat(hc);
        eat(yc);
    }

    //抽象(粒度)面向抽象編程(面向接口編程)
    public static void eat(Chicken c)
    {
        System.out.println("雞愛吃什么");
        c.eat();
    }
}

//雞
abstract class Chicken{
    private String name;
    public Chicken(){}
    public Chicken(String name)
    {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public abstract void eat();
}

//家雞
class HomeChicken extends Chicken{

    public HomeChicken(String name)
    {
        super(name);
    }
    @Override
    public void eat() {
        System.out.println(this.getName()+"我愛吃米");
    }
}

//野雞
class YeChicken extends Chicken{
    public YeChicken(String name)
    {
        super(name);
    }
    @Override
    public void eat() {
        System.out.println(this.getName()+"我愛吃蟲");
    }
}

運行效果:


image.png

向下轉(zhuǎn)型:將父類實例轉(zhuǎn)為子類實例

格式:子類 子類對象= (子類)父類實例; 強制轉(zhuǎn)換

代碼:

public class Demo {

    public static void main(String[] args) {
        //用父類的引用指向子類對象(用大的類型來表示小的類型),自動轉(zhuǎn)換(向上轉(zhuǎn)型)
        Chicken hc = new HomeChicken("小米");
        YeChicken yc = new YeChicken("大米");
        Chicken jc = new JianChicken();
        eat(jc);
    }

    //抽象(粒度)面向抽象編程(面向接口編程)
    public static void eat(Chicken c)
    {
        System.out.println("雞愛吃什么");
        c.eat();
        JianChicken jjc = (JianChicken)c;
        //大的類型轉(zhuǎn)換為小的類型,強制轉(zhuǎn)換(向下轉(zhuǎn)型)
        jjc.sing();
    }
}

//雞
abstract class Chicken{
    private String name;
    public Chicken(){}
    public Chicken(String name)
    {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public abstract void eat();
}

//家雞
class HomeChicken extends Chicken{

    public HomeChicken(String name)
    {
        super(name);
    }
    @Override
    public void eat() {
        System.out.println(this.getName()+"我愛吃米");
    }
}

//野雞
class YeChicken extends Chicken{
    public YeChicken(String name)
    {
        super(name);
    }
    @Override
    public void eat() {
        System.out.println(this.getName()+"我愛吃蟲");
    }
}

class JianChicken extends Chicken{

    @Override
    public void eat() {
        System.out.println("我不吃東西");
    }

    public void sing()
    {
        System.out.println("唧唧復(fù)唧唧,我是尖叫雞");
    }
}

運行效果:


image.png

三、多態(tài)性小結(jié)

1.方法的重載與重寫就是方法的多態(tài)性表現(xiàn)
2.多個子類就是父類中的多種形態(tài)
3.父類引用可以指向子類對象,自動轉(zhuǎn)換
4.子類對象指向父類引用需要強制轉(zhuǎn)換(注意:類型不對會報異常)
5.在實際開發(fā)中盡量使用父類引用(更利于擴展)

四、instanceof關(guān)鍵字

1.instanceof是用于檢查對象是否為指定的類型,通常在把父類引用強制轉(zhuǎn)換為子類引用時要使用,以避免發(fā)生類型轉(zhuǎn)換異常(ClassCastException)

//當我們需要把父類的實例強制轉(zhuǎn)換為子類引用時,為了避免類型轉(zhuǎn)換異常ClassCastException
//那么我們需要在轉(zhuǎn)換之前做類型檢查(判斷)
if(c instanceof JianChicken)  //成立的條件是,對象本身及對象的父類型,都可以通過檢查
        {
            JianChicken jjc = (JianChicken)c;
            //大的類型轉(zhuǎn)換為小的類型,強制轉(zhuǎn)換(向下轉(zhuǎn)型)
            jjc.sing();
        }

示例代碼:

public class Demo {

    public static void main(String[] args) {
        //用父類的引用指向子類對象(用大的類型來表示小的類型),自動轉(zhuǎn)換(向上轉(zhuǎn)型)
        Chicken hc = new HomeChicken("小米");
        YeChicken yc = new YeChicken("大米");
        Chicken jc = new JianChicken();
        eat(jc);
        eat(hc);
        eat(yc);
    }

    //抽象(粒度)面向抽象編程(面向接口編程)
    public static void eat(Chicken c)
    {
        System.out.println("雞愛吃什么");
        c.eat();
        //當我們需要把父類的實例強制轉(zhuǎn)換為子類引用時,為了避免類型轉(zhuǎn)換異常ClassCastException
        //那么我們需要在轉(zhuǎn)換之前做類型檢查(判斷)
        if(c instanceof JianChicken)
        {
            JianChicken jjc = (JianChicken)c;
            //大的類型轉(zhuǎn)換為小的類型,強制轉(zhuǎn)換(向下轉(zhuǎn)型)
            jjc.sing();
        }
    }
}

//雞
abstract class Chicken{
    private String name;
    public Chicken(){}
    public Chicken(String name)
    {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public abstract void eat();
}

//家雞
class HomeChicken extends Chicken{

    public HomeChicken(String name)
    {
        super(name);
    }
    @Override
    public void eat() {
        System.out.println(this.getName()+"我愛吃米");
    }
}

//野雞
class YeChicken extends Chicken{
    public YeChicken(String name)
    {
        super(name);
    }
    @Override
    public void eat() {
        System.out.println(this.getName()+"我愛吃蟲");
    }
}

class JianChicken extends Chicken{

    @Override
    public void eat() {
        System.out.println("我不吃東西");
    }

    public void sing()
    {
        System.out.println("唧唧復(fù)唧唧,我是尖叫雞");
    }
}

運行效果:


image.png

四、父類設(shè)計法則

1.父類通常情況下都設(shè)計為抽象類或接口,其中優(yōu)先考慮接口,如接口不能滿足才考慮抽象類
2.一個具體的類盡可能不去繼承另一個具體類,這樣的好處是無需檢查對象是否為父類的對象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容