欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java多態(tài)實(shí)現(xiàn)原理詳細(xì)梳理總結(jié)

 更新時(shí)間:2022年06月15日 09:17:54   作者:? 共飲一杯無(wú)?  ?  
這篇文章主要介紹了Java多態(tài)實(shí)現(xiàn)原理詳細(xì)梳理總結(jié),多態(tài)是繼封裝、繼承之后,面向?qū)ο蟮牡谌筇匦?,本文只總結(jié)了多態(tài)的實(shí)現(xiàn)原理,需要的朋友可以參考一下

一、概述

引入

多態(tài)是繼封裝、繼承之后,面向?qū)ο蟮牡谌筇匦?。生活中,比如跑的?dòng)作,小貓、小狗和大象,跑起來(lái)是不一樣的。再比如飛的動(dòng)作,昆蟲(chóng)、鳥(niǎo)類(lèi)和飛機(jī),飛起來(lái)也是不一樣的??梢?jiàn),同一行為,通過(guò)不同的事物,可以體現(xiàn)出來(lái)的不同的形態(tài)。多態(tài),描述的就是這樣的狀態(tài)。

定義

多態(tài): 是指同一行為,具有多個(gè)不同表現(xiàn)形式。

二、多態(tài)的體現(xiàn)

多態(tài)體現(xiàn)的格式:

父類(lèi)類(lèi)型 變量名 = new 子類(lèi)對(duì)象;
變量名.方法名();

父類(lèi)類(lèi)型:指子類(lèi)對(duì)象繼承的父類(lèi)類(lèi)型,或者實(shí)現(xiàn)的父接口類(lèi)型。

代碼如下:

Fu f = new Zi();
f.method();

當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類(lèi)中是否有該方法,如果沒(méi)有,則編譯錯(cuò)誤;如果有,執(zhí)行的是子類(lèi)重寫(xiě)后方法。

代碼如下:

定義父類(lèi):

public abstract class Animal {
    public abstract void eat();
}

定義子類(lèi):

class Cat extends Animal {
    public void eat() {
        System.out.println("吃魚(yú)??");
    }
}
class Dog extends Animal {
    public void eat() {
        System.out.println("吃骨頭??");
    }
}

定義測(cè)試類(lèi):

public class Test {
    public static void main(String[] args) {
        // 多態(tài)形式,創(chuàng)建對(duì)象
        Animal a1 = new Cat();
        // 調(diào)用的是 Cat 的 eat
        a1.eat();
        // 多態(tài)形式,創(chuàng)建對(duì)象
        Animal a2 = new Dog();
        // 調(diào)用的是 Dog 的 eat
        a2.eat();
    }
}

三、多態(tài)的好處

實(shí)際開(kāi)發(fā)的過(guò)程中,父類(lèi)類(lèi)型作為方法形式參數(shù),傳遞子類(lèi)對(duì)象給方法,進(jìn)行方法的調(diào)用,更能體現(xiàn)出多態(tài)的擴(kuò)展性與便利

定義父類(lèi):

public abstract class Animal {
    public abstract void eat();
}

定義子類(lèi):

class Cat extends Animal {
    public void eat() {
        System.out.println("吃魚(yú)??");
    }
}
class Dog extends Animal {
    public void eat() {
        System.out.println("吃骨頭??");
    }
}

定義測(cè)試類(lèi):

public class Test {
    public static void main(String[] args) {
        // 多態(tài)形式,創(chuàng)建對(duì)象
        Cat c = new Cat();
        Dog d = new Dog();
        // 調(diào)用showCatEat
        showCatEat(c);
        // 調(diào)用showDogEat
        showDogEat(d);
        /**
        以上兩個(gè)方法, 均可以被showAnimalEat(Animal a)方法所替代
        而執(zhí)行效果一致
        */
        showAnimalEat(c);
        showAnimalEat(d);
    }
    public static void showCatEat (Cat c){
        c.eat();
    }
    public static void showDogEat (Dog d){
        d.eat();
    }
    public static void showAnimalEat (Animal a){
        a.eat();
    }
}

由于多態(tài)特性的支持,showAnimalEat方法的Animal類(lèi)型,是Cat和Dog的父類(lèi)類(lèi)型,父類(lèi)類(lèi)型接收子類(lèi)對(duì)象,當(dāng)然可以把Cat對(duì)象和Dog對(duì)象,傳遞給方法。
當(dāng)eat方法執(zhí)行時(shí),多態(tài)規(guī)定,執(zhí)行的是子類(lèi)重寫(xiě)的方法,那么效果自然與showCatEat、showDogEat方法一致,
所以showAnimalEat完全可以替代以上兩方法。
不僅僅是替代,在擴(kuò)展性方面,無(wú)論之后再多的子類(lèi)出現(xiàn),我們都不需要編寫(xiě)showXxxEat方法了,直接使用
showAnimalEat都可以完成。
所以,多態(tài)的好處,體現(xiàn)在,可以使程序編寫(xiě)的更簡(jiǎn)單,并有良好的擴(kuò)展。

四、引用類(lèi)型轉(zhuǎn)換

多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型與向下轉(zhuǎn)型兩種:

向上轉(zhuǎn)型

向上轉(zhuǎn)型:多態(tài)本身是子類(lèi)類(lèi)型向父類(lèi)類(lèi)型向上轉(zhuǎn)換的過(guò)程,這個(gè)過(guò)程是默認(rèn)的。當(dāng)父類(lèi)引用指向一個(gè)子類(lèi)對(duì)象時(shí),便是向上轉(zhuǎn)型。

使用格式:

父類(lèi)類(lèi)型 變量名 = new 子類(lèi)類(lèi)型();
如:Animal a = new Cat();

向下轉(zhuǎn)型

向下轉(zhuǎn)型:父類(lèi)類(lèi)型向子類(lèi)類(lèi)型向下轉(zhuǎn)換的過(guò)程,這個(gè)過(guò)程是強(qiáng)制的。
一個(gè)已經(jīng)向上轉(zhuǎn)型的子類(lèi)對(duì)象,將父類(lèi)引用轉(zhuǎn)為子類(lèi)引用,可以使用強(qiáng)制類(lèi)型轉(zhuǎn)換的格式,便是向下轉(zhuǎn)型。

使用格式:

子類(lèi)類(lèi)型 變量名 = (子類(lèi)類(lèi)型) 父類(lèi)變量名;
如:Cat c =(Cat) a;

為什么要轉(zhuǎn)型

當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類(lèi)中是否有該方法,如果沒(méi)有,則編譯錯(cuò)誤。也就是說(shuō),不能調(diào)用子類(lèi)擁有,而父類(lèi)沒(méi)有的方法。編譯都錯(cuò)誤,更別說(shuō)運(yùn)行了。這也是多態(tài)給我們帶來(lái)的一點(diǎn)"小麻煩"。所以,想要調(diào)用子類(lèi)特有的方法,必須做向下轉(zhuǎn)型。

轉(zhuǎn)型演示,代碼如下:

定義類(lèi):

abstract class Animal {
    abstract void eat();
}
class Cat extends Animal {
    public void eat() {
        System.out.println("吃魚(yú)??");
    }
    public void catchMouse() {
        System.out.println("抓老鼠??");
    }
}
class Dog extends Animal {
    public void eat() {
        System.out.println("吃骨頭??");
    }
    public void watchHouse() {
        System.out.println("看家??");
    }
}

定義測(cè)試類(lèi):

public static void main(String[] args) {
    // 向上轉(zhuǎn)型
    Animal a = new Cat();
    a.eat(); // 調(diào)用的是 Cat 的 eat
    // 向下轉(zhuǎn)型
    Cat c = (Cat)a;
    c.catchMouse(); // 調(diào)用的是 Cat 的 catchMouse
}

轉(zhuǎn)型的異常

轉(zhuǎn)型的過(guò)程中,一不小心就會(huì)遇到這樣的問(wèn)題,請(qǐng)看如下代碼:

public class Test {
    public static void main(String[] args) {
        // 向上轉(zhuǎn)型
        Animal a = new Cat();
        a.eat(); // 調(diào)用的是 Cat 的 eat
        // 向下轉(zhuǎn)型
        Dog d = (Dog)a;
        d.watchHouse(); // 調(diào)用的是 Dog 的 watchHouse 【運(yùn)行報(bào)錯(cuò)】
    }
}

這段代碼可以通過(guò)編譯,但是運(yùn)行時(shí),卻報(bào)出了 ClassCastException ,類(lèi)型轉(zhuǎn)換異常!這是因?yàn)椋髅鲃?chuàng)建了Cat類(lèi)型對(duì)象,運(yùn)行時(shí),當(dāng)然不能轉(zhuǎn)換成Dog對(duì)象的。這兩個(gè)類(lèi)型并沒(méi)有任何繼承關(guān)系,不符合類(lèi)型轉(zhuǎn)換的定義。為了避免ClassCastException的發(fā)生,Java提供了 instanceof 關(guān)鍵字,給引用變量做類(lèi)型的校驗(yàn),格式如下:

變量名 instanceof 數(shù)據(jù)類(lèi)型
如果變量屬于該數(shù)據(jù)類(lèi)型,返回true。
如果變量不屬于該數(shù)據(jù)類(lèi)型,返回false。

所以,轉(zhuǎn)換前,我們最好先做一個(gè)判斷,代碼如下:

public class Test {
    public static void main(String[] args) {
    // 向上轉(zhuǎn)型
        Animal a = new Cat();
        a.eat(); // 調(diào)用的是 Cat 的 eat
        // 向下轉(zhuǎn)型
        if (a instanceof Cat){
            Cat c = (Cat)a;
            c.catchMouse(); // 調(diào)用的是 Cat 的 catchMouse
        } else if (a instanceof Dog){
            Dog d = (Dog)a;
            d.watchHouse(); // 調(diào)用的是 Dog 的 watchHouse
        }
    }
}

到此這篇關(guān)于Java多態(tài)實(shí)現(xiàn)原理詳細(xì)梳理總結(jié)的文章就介紹到這了,更多相關(guān)Java 多態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java+Swing實(shí)現(xiàn)五子棋游戲的示例代碼

    Java+Swing實(shí)現(xiàn)五子棋游戲的示例代碼

    本文將通過(guò)Java語(yǔ)言實(shí)現(xiàn)經(jīng)典游戲—五子棋游戲,文中采用了Swing制作游戲界面,具有開(kāi)始游戲,悔棋,認(rèn)輸,退出等功能。感興趣的可以跟隨小編一起動(dòng)手試一試
    2022-02-02
  • 解決外部jar包@Service無(wú)法注解無(wú)法掃描的問(wèn)題

    解決外部jar包@Service無(wú)法注解無(wú)法掃描的問(wèn)題

    這篇文章主要介紹了解決外部jar包@Service無(wú)法注解無(wú)法掃描的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java程序員必會(huì)的遠(yuǎn)程debug教程

    java程序員必會(huì)的遠(yuǎn)程debug教程

    這篇文章主要為大家介紹了java程序員必會(huì)的遠(yuǎn)程debug教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Java編程基于快速排序的三個(gè)算法題實(shí)例代碼

    Java編程基于快速排序的三個(gè)算法題實(shí)例代碼

    這篇文章主要介紹了Java編程基于快速排序的三個(gè)算法題實(shí)例代碼,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • 關(guān)于SpringBoot配置文件加載位置的優(yōu)先級(jí)

    關(guān)于SpringBoot配置文件加載位置的優(yōu)先級(jí)

    這篇文章主要介紹了關(guān)于SpringBoot配置文件加載位置的優(yōu)先級(jí),我們也可以通過(guò)spring.config.location來(lái)改變默認(rèn)的配置文件位置,項(xiàng)目打包好后,我們可以通過(guò)命令行的方式在啟動(dòng)時(shí)指定配置文件的位置,需要的朋友可以參考下
    2023-10-10
  • 一文詳解RabbitMQ如何保證消息可靠性

    一文詳解RabbitMQ如何保證消息可靠性

    這篇文章將詳細(xì)介紹RabbitMQ的消息可靠性機(jī)制,如消息丟失,消息重復(fù)性消費(fèi),消息積壓等問(wèn)題,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-07-07
  • java排查進(jìn)程占用系統(tǒng)內(nèi)存高方法

    java排查進(jìn)程占用系統(tǒng)內(nèi)存高方法

    這篇文章主要為大家介紹了java進(jìn)程占用系統(tǒng)內(nèi)存高排查方法,
    2023-06-06
  • Java你不了解的大數(shù)型BigInteger與BigDecimal類(lèi)

    Java你不了解的大數(shù)型BigInteger與BigDecimal類(lèi)

    這篇文章主要介紹了Java 處理超大數(shù)類(lèi)型之BigInteger與BigDecimal案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2022-05-05
  • Java中線程組ThreadGroup與線程池的區(qū)別及示例

    Java中線程組ThreadGroup與線程池的區(qū)別及示例

    這篇文章主要介紹了Java中線程組與線程池的區(qū)別及示例,ThreadGroup是用來(lái)管理一組線程的,可以控制線程的執(zhí)行,查看線程的執(zhí)行狀態(tài)等操作,方便對(duì)于一組線程的統(tǒng)一管理,需要的朋友可以參考下
    2023-05-05
  • java處理按鈕點(diǎn)擊事件的方法

    java處理按鈕點(diǎn)擊事件的方法

    下面小編就為大家?guī)?lái)一篇java處理按鈕點(diǎn)擊事件的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04

最新評(píng)論