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

Java多態(tài)中的向上轉(zhuǎn)型與向下轉(zhuǎn)型淺析

 更新時(shí)間:2023年02月16日 09:58:19   作者:烽起黎明  
多態(tài)是指不同類的對象在調(diào)用同一個(gè)方法是所呈現(xiàn)出的多種不同行為,下面這篇文章主要給大家介紹了關(guān)于Java多態(tài)中向上轉(zhuǎn)型與向下轉(zhuǎn)型的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

向上轉(zhuǎn)型

概念明細(xì)

【原理】:實(shí)際就是創(chuàng)建一個(gè)子類對象,將其當(dāng)成父類對象來使用.

語法格式:父類類型 對象名 = new 子類類型()

Animal animal = new Cat("元寶",2);	
//animal是父類類型,但可以引用一個(gè)子類對象,因?yàn)槭菑男》秶虼蠓秶霓D(zhuǎn)換

以下是定義的父類Animal類它的兩個(gè)繼承類Cat類和Dog類,分別重寫了Animal類的eat()方法

class Animal{
     String name;
     int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(age + "歲的" + name + "正在吃東西");
    }
}

class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(age + "歲的" + name + "正在吃貓糧");
    }
}

class Dog extends Animal {
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(age + "歲的" + name + "正在吃狗糧");
    }
}

使用場景1:直接賦值

以下這種就是直接賦值類型的向上轉(zhuǎn)型,將子類對象的引用給到父類對象。然后再將這個(gè)對象作為參數(shù)傳遞進(jìn)去,就可以根據(jù)不同引用調(diào)用不同的行為

public class Test1 {
    public static void eat(Animal animal)
    {
        animal.eat();
    }
    public static void main(String[] args) {
        Animal animal1 = new Animal("動物",3);
        Animal animal2 = new Cat("加菲貓",2);
        Animal animal3 = new Dog("哈士奇",1);
        
        eat(animal1);
        eat(animal2);
        eat(animal3);
    }
}

使用場景2:

方法傳參 第二種方法傳參很簡單,我們連對象都不需要?jiǎng)?chuàng)建,只需要直接將三種不同對象的引用作為實(shí)參傳遞給到eat()中的形參接受,就可以產(chǎn)生【向上轉(zhuǎn)型】

public class Test1 {
    public static void eat(Animal animal)
    {
        animal.eat();
    }
    public static void main(String[] args) {
        eat(new Animal("動物",3));
        eat(new Cat("加菲貓",2));
        eat(new Dog("哈士奇",1));
    }
}

使用場景3:

方法返回 第三種便是在一個(gè)方法中將不同對象的引用進(jìn)行返回,然后傳遞給到父類對象,也可以產(chǎn)生向上轉(zhuǎn)型

public static void eat(Animal animal)
{
    animal.eat();
}

稍微講一下這個(gè)方法,可以看到形參是String字符類型,在方法中通過判斷外界傳入進(jìn)來的字符串然后對應(yīng)地進(jìn)行返回

  •  若是“貓”就返Cat對象的引用;
  •  若是“狗”就返Dog對象的引用;
  •  若是其他就返null
public static Animal BuyAnimal(String var)
{
    if(var.equals("貓")){
        return new Cat("加菲貓",2);
    }else if(var.equals("狗")){
        return new Dog("哈士奇",1);
    }else{
        return null;
    }
}
Animal animal1 = BuyAnimal("貓");
eat(animal1);
Animal animal2 = BuyAnimal("狗");
eat(animal2);
Animal animal3 = BuyAnimal("兔");
eat(animal3);

然后可以看到,前兩個(gè)傳入的是【貓】和【狗】,因此執(zhí)行的便是不同對象的行為,但是在最后傳入了【兔】,因此在BuyAnimal()方法中會return null

這就使得傳入eat()方法中去調(diào)用相關(guān)對象的行為時(shí)因?yàn)椴淮嬖谶@個(gè)對象的引用,所以就會產(chǎn)生空指針異常

上述便是向上轉(zhuǎn)型的三種場景。學(xué)會辨別和使用即可

向上轉(zhuǎn)型的優(yōu)缺點(diǎn)

【優(yōu)點(diǎn)】:讓代碼實(shí)現(xiàn)更簡單靈活,這個(gè)從上面的三個(gè)不同場景就可以看得出來

【缺點(diǎn)】:不能調(diào)用到子類特有的方法??

比如說我在Dog類中寫了一個(gè)它自己獨(dú)有的方法lookdoor()

class Dog extends Animal {
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(age + "歲的" + name + "正在吃狗糧");
    }

    public void lookdoor(){
        System.out.println(name + "在看門");
    }
}

但是可以看到,我在通過向上轉(zhuǎn)型之后通過父類對象接受子類引用但是調(diào)用不到子類中特有的方法,這其實(shí)就是向上轉(zhuǎn)型的缺陷

【注意事項(xiàng)】

  • 上轉(zhuǎn)型對象不可以訪問子類新增的成員變量和子類自己新增的方法,因?yàn)檫@是子類獨(dú)有的,而父類中沒有
  • 上轉(zhuǎn)型對象可以訪問子類繼承的方法或者是子類重寫的方法,這個(gè)時(shí)候當(dāng)上轉(zhuǎn)型對象去調(diào)用這個(gè)方法時(shí),一定是調(diào)用了子類重寫后的方法,這就是我們前面在講繼承的時(shí)候所提到的方法重寫
  • 不可以將父類創(chuàng)建的對象的引用賦值給子類聲明的對象,也就是下面的這兩句代碼,這很明顯和我們的上轉(zhuǎn)型對象相反的,我們是將子類對象給到父類的引用,但這是將父類的引用給到子類的對象,完全就是顛倒黑白【就和貓是動物,動物卻不是貓??一個(gè)道理】

向下轉(zhuǎn)型

接下去我們來講講向下轉(zhuǎn)型,這種類型的轉(zhuǎn)化不太安全,如果沒有特殊需求,不建議使用

向下轉(zhuǎn)型解決【調(diào)用子類獨(dú)有方法】

繼續(xù)上面的談到的在向上轉(zhuǎn)型之后無法調(diào)用子類獨(dú)有的方法這個(gè)問題,其實(shí)向下轉(zhuǎn)型就可以解決,代碼如下

Animal animal1 = new Dog("哈士奇",1);
animal1.eat();
//animal1.lookdoor();
Dog dog = (Dog) animal1;
dog.lookdoor();

可以看到,也就是將父類的對象animal強(qiáng)轉(zhuǎn)成為Dog狗類的對象,這樣的話其實(shí)就可以去調(diào)用子類中特有的方法了

向下轉(zhuǎn)型的缺陷

那為什么說向下轉(zhuǎn)型不安全呢,因?yàn)樗嬖诎踩[患

Animal animal1 = new Cat("加菲貓",2);
animal1.eat();
//animal1.lookdoor();
Dog dog = (Dog) animal1;
dog.lookdoor();

可以看到我將原先的Dog狗類變?yōu)榱?code>Cat貓類,此時(shí)animal就得到了貓類對象的引用,但是在下面可以看到如果將這個(gè)animal強(qiáng)轉(zhuǎn)為Dog狗類的對象其實(shí)就會出問題了

看到編譯器報(bào)出了ClassCastException —— 類型轉(zhuǎn)換異常

向下轉(zhuǎn)型的優(yōu)化

??向下轉(zhuǎn)型用的比較少,而且不安全,萬一轉(zhuǎn)換失敗,運(yùn)行時(shí)就會拋異常。

??Java中為了提高向下轉(zhuǎn)型的安全性,引入了 instanceof ,如果該表達(dá)式為true,則可以安全轉(zhuǎn)換

可以看到,在進(jìn)行強(qiáng)轉(zhuǎn)之前我通過instanceof這個(gè)關(guān)鍵字進(jìn)行了一下判斷,看看animal1是否獲取到了Dog類的引用,若是才可以進(jìn)行強(qiáng)制類型轉(zhuǎn)化,若不是的話就不會進(jìn)行任何操作

Animal animal1 = new Cat("加菲貓",2);
animal1.eat();
//animal1.lookdoor();
if(animal1 instanceof Dog){   //判斷一下animal1是否獲取到了Dog類的引用
  Dog dog = (Dog) animal1;
  dog.lookdoor();
}

如果對instance關(guān)鍵字感興趣的可以看看官方的文檔 ——> instanceof關(guān)鍵字

再度對比二者【碎碎念】

可能在上面這一系列說來有點(diǎn)難分辨,我們再來對比看看

其實(shí)你可以這么去想Animal animal1 = new Cat可以看成是貓歸屬于一個(gè)動物類,那貓一定是屬于動物的

但是看到Dog dog = (Dog) animal1其實(shí)就要去思考把動物歸屬于狗,這其實(shí)是說不通的,難道只要是動物就一定是狗嗎?那可不一定,動物可多的是

總結(jié)與提煉

來總結(jié)一下本文所學(xué)到的內(nèi)容

  • 在本文中我們講到了多態(tài)中的【向上轉(zhuǎn)型】與【向下轉(zhuǎn)型】
  • 首先是說到了向上轉(zhuǎn)型,介紹了它會出現(xiàn)的三種場景,也分析了它的優(yōu)缺點(diǎn),知道了在向下轉(zhuǎn)型之后無法調(diào)用子類特有的方法
  • 但是在向下轉(zhuǎn)型中,我們解決了這個(gè)問題,通過對父類對象進(jìn)行一個(gè)強(qiáng)轉(zhuǎn),就可以調(diào)用到子類當(dāng)中的方法,不過可以看到這種做法不太安全,若是一開始父類對象接受了一個(gè)子類的引用,但是在強(qiáng)轉(zhuǎn)的時(shí)候轉(zhuǎn)化為了另外一個(gè)子類,就會造成類型轉(zhuǎn)換的問題
  • 于是后面對方法進(jìn)行了修正,在前面加上了instanceof關(guān)鍵字進(jìn)行一個(gè)判斷,只有父類接收到了這個(gè)子類的引用,才可以強(qiáng)轉(zhuǎn)為這個(gè)子類的對象

到此這篇關(guān)于Java多態(tài)中的向上轉(zhuǎn)型與向下轉(zhuǎn)型的文章就介紹到這了,更多相關(guān)Java多態(tài)向上轉(zhuǎn)型與向下轉(zhuǎn)型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java?中不全部使用?Static?方法的理由

    Java?中不全部使用?Static?方法的理由

    這篇文章主要介紹了Java?中不全部使用?Static?方法的理由,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • 淺談Spring Cloud Eureka 自我保護(hù)機(jī)制

    淺談Spring Cloud Eureka 自我保護(hù)機(jī)制

    這篇文章主要介紹了淺談Spring Cloud Eureka 自我保護(hù)機(jī)制,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • java加解密RSA使用方法代碼示例

    java加解密RSA使用方法代碼示例

    這篇文章主要介紹了java加解密RSA使用方法代碼示例,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。
    2017-10-10
  • 基于Jmeter生成測試報(bào)告過程圖解

    基于Jmeter生成測試報(bào)告過程圖解

    這篇文章主要介紹了基于Jmeter生成測試報(bào)告過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • springCloud中的Sidecar多語言支持詳解

    springCloud中的Sidecar多語言支持詳解

    這篇文章主要介紹了springCloud中的Sidecar多語言支持詳解,Sidecar是將一組緊密結(jié)合的任務(wù)與主應(yīng)用程序共同放在一臺主機(jī)Host中,但會將它們部署在各自的進(jìn)程或容器中,需要的朋友可以參考下
    2024-01-01
  • 一步步帶你入門Java中File類

    一步步帶你入門Java中File類

    java.io.File類是文件和目錄路徑名的抽象表示形式,主要用于文件和目錄的創(chuàng)建、查找和刪除等操作,下面這篇文章主要給大家介紹了關(guān)于入門Java中File類的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • Spring cloud 查詢返回廣告創(chuàng)意實(shí)例代碼

    Spring cloud 查詢返回廣告創(chuàng)意實(shí)例代碼

    在本篇文章里小編給大家整理的是關(guān)于Spring cloud 查詢返回廣告創(chuàng)意實(shí)例代碼,需要的朋友們可以跟著學(xué)習(xí)下。
    2019-08-08
  • 簡單了解Spring Framework5.0新特性

    簡單了解Spring Framework5.0新特性

    這篇文章主要介紹了簡單了解Spring Framework5.0新特性,涉及了核心框架修訂,核心容器更新,使用Kotlin進(jìn)行函數(shù)式編程等幾個(gè)方面的介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java異常處理方法匯總

    Java異常處理方法匯總

    這篇文章主要介紹了Java異常處理方法匯總,我們在軟件開發(fā)的過程中,任何語言的開發(fā)過程中都離不開異常處理。下面下小編加來給大家分享各種異常處理,希望對大家有所幫助,需要的朋友可以參考一下
    2021-12-12
  • springmvc接收參數(shù)為日期類型詳解

    springmvc接收參數(shù)為日期類型詳解

    這篇文章主要介紹了springmvc接收參數(shù)為日期類型,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09

最新評論