最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java對(duì)象類(lèi)型轉(zhuǎn)換和多態(tài)性(實(shí)例講解)

 更新時(shí)間:2017年10月30日 08:41:22   作者:java部落  
下面小編就為大家?guī)?lái)一篇java對(duì)象類(lèi)型轉(zhuǎn)換和多態(tài)性(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

對(duì)象類(lèi)型轉(zhuǎn)換

分為向上轉(zhuǎn)型和向下轉(zhuǎn)型(強(qiáng)制對(duì)象轉(zhuǎn)型)。 向上轉(zhuǎn)型是子對(duì)象向父對(duì)象轉(zhuǎn)型的過(guò)程,例如貓類(lèi)轉(zhuǎn)換為動(dòng)物類(lèi);向下轉(zhuǎn)型是強(qiáng)制轉(zhuǎn)型實(shí)現(xiàn)的,是父對(duì)象強(qiáng)制轉(zhuǎn)換為子對(duì)象。 這和基礎(chǔ)數(shù)據(jù)類(lèi)型的轉(zhuǎn)換是類(lèi)似的,byte在需要時(shí)會(huì)自動(dòng)轉(zhuǎn)換為int(向上轉(zhuǎn)型),int可以強(qiáng)制轉(zhuǎn)型為byte(向下轉(zhuǎn)型)。

對(duì)于對(duì)象轉(zhuǎn)型來(lái)說(shuō), 向上轉(zhuǎn)型后子對(duì)象獨(dú)有的成員將不可訪問(wèn) 。 意思是,在需要一只動(dòng)物時(shí),可以把貓當(dāng)作一只動(dòng)物傳遞,因?yàn)樨埨^承自動(dòng)物,貓具有動(dòng)物的所有屬性。但向上轉(zhuǎn)型后,貓不再是貓,而是被當(dāng)作動(dòng)物看待,它自己獨(dú)有的屬性和方法就不可見(jiàn)了。換句話(huà)說(shuō),向上轉(zhuǎn)型后,只能識(shí)別父對(duì)象中的內(nèi)容。

可以通過(guò)"引用變量 instanceof 類(lèi)名"的方式來(lái)判斷引用變量 所指向的對(duì)象 是否屬于某個(gè)類(lèi),也就是說(shuō)"對(duì)象是不是某類(lèi)",例如聲明一個(gè)貓類(lèi)對(duì)象的引用"Cat c",然后"c instanceof Animal"表述的意思是"對(duì)象c是一種動(dòng)物嗎?"對(duì)于instanceof返回true的對(duì)象,都可以轉(zhuǎn)換為類(lèi)對(duì)象,只不過(guò)有些可能需要強(qiáng)制轉(zhuǎn)換。

向上轉(zhuǎn)型可以自動(dòng)進(jìn)行,這本就是符合邏輯的,狗類(lèi)繼承自動(dòng)物類(lèi),它本身就是一只動(dòng)物,因此在需要?jiǎng)游镱?lèi)的時(shí)候,丟一只狗過(guò)去就會(huì)自動(dòng)向上轉(zhuǎn)型成動(dòng)物類(lèi)。但這時(shí)狗已經(jīng)不是狗,而是動(dòng)物,所以狗獨(dú)有的成員不再可見(jiàn)。

強(qiáng)制轉(zhuǎn)換的方式和基礎(chǔ)數(shù)據(jù)類(lèi)型強(qiáng)制轉(zhuǎn)換一樣,都是在待轉(zhuǎn)換對(duì)象前加上目標(biāo)類(lèi)型,例如將動(dòng)物a強(qiáng)制轉(zhuǎn)換為狗d: Dog d = (Dog)a 。

下面是一個(gè)對(duì)象類(lèi)型轉(zhuǎn)換的示例,很好地分析了能否轉(zhuǎn)型、轉(zhuǎn)型后能否訪問(wèn)某些成員等等。

class Animal {
 String name;
 Animal(String name) {this.name = name;}
}

class Cat extends Animal {
 String eyecolor;
 Cat(String name,String color) {super(name); this.eyecolor = color;}
}

class Dog extends Animal {
 String furcolor;
 Dog(String name,String color) {super(name); this.furcolor = color;}
}

public class OCast {
 public static void main(String [] args) {
 Animal a = new Animal("animal");
 Cat c = new Cat("cat","blue");
 Dog d = new Dog("dog","black");

 System.out.println( a instanceof Animal);//return true
 System.out.println( c instanceof Animal);//return true
 System.out.println( d instanceof Animal);//return true
 System.out.println( a instanceof Cat); //return false

 System.out.println(a.name); //return animal
 a = new Dog("yellowdog","yellow"); //object Dog upcast to Animal
 System.out.println(a.name);  //return yellowdog
 System.out.println(a instanceof Animal); //return true
 System.out.println(a instanceof Dog); //return true
 //System.out.println(a.furcolor); //error! because a was regarded as Animal
 Dog d1 = (Dog)a; // because "a instanceof Dog" is true,so force cast Animal a to Dog
 System.out.println(d1.furcolor);  //return yellow
 }
}

對(duì)于上面的 a = new Dog("yellowdog",yellow) ,a是Animal類(lèi)型,但此時(shí) 它指向的是Dog對(duì)象。也就是說(shuō)它是Dog,所以也是Animal類(lèi) ,所以 a instanceof Animal); 和 a instanceof Dog; 都是true,這是它的"指針"決定的。 但因?yàn)樗念?lèi)型是Animal類(lèi)型,類(lèi)型決定了能存儲(chǔ)什么樣的數(shù)據(jù),對(duì)于已經(jīng)存在的但不符合類(lèi)型的數(shù)據(jù)都是不可見(jiàn)的,所以Animal類(lèi)型決定了它只能看到Dog對(duì)象中的Animal部分 。

如下圖:

既然可以向上轉(zhuǎn)型,配合instanceof的邏輯判斷,就能實(shí)現(xiàn)很好的擴(kuò)展性。例如,動(dòng)物類(lèi)的sing(Animal a)方法需要的是一個(gè)動(dòng)物類(lèi),可以給它一只狗d,這時(shí)會(huì)向上轉(zhuǎn)型(就像需要double類(lèi)型卻給了一個(gè)int數(shù)據(jù)一樣),雖然轉(zhuǎn)型了,但狗d的實(shí)際引用仍然是Dog對(duì)象,于是 if (a instanceof Dog) 判斷為真,則調(diào)用能體現(xiàn)狗sing()方法特殊性的語(yǔ)句。如果傳遞一只貓,if判斷一下并調(diào)用能體現(xiàn)貓sing()方法特殊性的語(yǔ)句。這樣,任何時(shí)候想添加一只動(dòng)物,都只需要增加一條if語(yǔ)句就可以了。

見(jiàn)下面的示例:

class Animal {
 String name;
 Animal(String name) {
 this.name = name;
 }
}

class Cat extends Animal {Cat(String name) {super(name);}}
class Dog extends Animal {Dog(String name) {super(name);}}

public class TestCast {
 public static void main(String [] args) {
 TestCast t = new TestCast(); 
 Animal a = new Animal("animal");
 Animal c = new Cat("cat");
 Animal d = new Dog("dog");
 t.sing(a);t.sing(c);t.sing(d);
 }

 void sing(Animal a) {
 if ( a instanceof Cat) {
  Cat cat = (Cat)a;
  System.out.println("cat is singing");
 } else if(a instanceof Dog) {
  Dog dog = (Dog)a;
  System.out.println("dog is singing");
 } else {
  System.out.println("not an instance of animal");
 }
 }
}

如果沒(méi)有對(duì)象轉(zhuǎn)型,那么Dog里要定義一次sing(),Cat里也要定義一次sing()。要增加一個(gè)動(dòng)物類(lèi),動(dòng)物類(lèi)里也還要定義一次sing()。現(xiàn)在就方便多了,直接在sing()方法內(nèi)部修改if語(yǔ)句就可以了。

注意,上面的sing()方法不屬于Animal或其他子類(lèi)的方法,而是獨(dú)立定義在其他類(lèi)里進(jìn)行調(diào)用的。

多態(tài)

向上轉(zhuǎn)型雖然在一定程度上提高了可擴(kuò)展性,但提高的程度并不太高。以向上轉(zhuǎn)型為基礎(chǔ),java的多態(tài)實(shí)現(xiàn)的擴(kuò)展性更好更方便。

多態(tài)也叫動(dòng)態(tài)綁定或后期綁定,它是執(zhí)行期間進(jìn)行的綁定,而非編譯期間的綁定(這是靜態(tài)綁定或稱(chēng)為前期綁定)。

多態(tài)的原理是:當(dāng)向上轉(zhuǎn)型后,調(diào)用一個(gè)被重寫(xiě)的方法時(shí),本該調(diào)用的是父類(lèi)方法,但實(shí)際上卻會(huì)動(dòng)態(tài)地調(diào)用子類(lèi)重寫(xiě)后的方法。實(shí)際上,編譯期間綁定的確實(shí)是父類(lèi)方法,只不過(guò)在執(zhí)行期間動(dòng)態(tài)轉(zhuǎn)調(diào)子類(lèi)對(duì)應(yīng)方法。

例如,Animal類(lèi)的sing()方法,Cat和Dog類(lèi)都重寫(xiě)了sing()方法。當(dāng)需要一個(gè)Animal對(duì)象時(shí),傳遞了一個(gè)Cat類(lèi),那么將調(diào)用Cat的sing()方法。動(dòng)態(tài)綁定的邏輯正如下面的代碼類(lèi)似:

void sing(Animal a) {
 if ( a instanceof Cat) {
 Cat cat = (Cat)a;
 System.out.println("cat is singing");
 } else if(a instanceof Dog) {
 Dog dog = (Dog)a;
 System.out.println("dog is singing");
 } else {
 System.out.println("not an instance of animal");
 }
}

以下是一個(gè)多態(tài)的例子

class Animal {
 private String name;
 Animal(String name) {this.name = name;}

 public void sing(){System.out.println("animal sing...");}
}

class Cat extends Animal {
 private String eyeColor;
 Cat(String n,String c) {super(n); eyeColor = c;}

 public void sing() {System.out.println("cat sing...");}
}

class Dog extends Animal {
 private String furColor;
 Dog(String n,String c) {super(n); furColor = c;}

 public void sing() {System.out.println("dog sing...");}
}

class Lady {
 private String name;
 private Animal pet;
 Lady(String name,Animal pet) {this.name = name; this.pet = pet;}
 public void myPetSing(){pet.sing();}
}

public class DuoTai {
 public static void main(String args[]){
 Cat c = new Cat("catname","blue");
 Dog d = new Dog("dogname","black");
 Lady l1 = new Lady("l1",c);
 Lady l2 = new Lady("l2",d);
 l1.myPetSing();
 l2.myPetSing();
 }
}

編譯后的執(zhí)行結(jié)果為:

cat sing...
dog sing...

在上面的示例中,Lady類(lèi)的構(gòu)造方法和她調(diào)用sing()方法的代碼為:

Lady(String name,Animal pet) {this.name = name; this.pet = pet;}
public void myPetSing(){pet.sing();}

如果構(gòu)造出Lady對(duì)象的pet是Cat對(duì)象c,這個(gè)c首先會(huì)向上轉(zhuǎn)型為Animal類(lèi),也就是說(shuō)Lady的pet屬性雖然指向的是"Cat c"對(duì)象,但它只能看見(jiàn)其中的父對(duì)象Animal部分。那么 myPetSing(pet.sing();) 方法自然會(huì)調(diào)用Animal類(lèi)的sing()方法。 以上過(guò)程是編譯器所認(rèn)為的過(guò)程,也是靜態(tài)綁定或前期綁定的過(guò)程。

但編譯完成后,雖然pet屬性只能看見(jiàn)Animal部分,但實(shí)際在執(zhí)行時(shí)pet.sing()卻換轉(zhuǎn)換為執(zhí)行c.sing()。就相當(dāng)于做了一次對(duì)象類(lèi)型強(qiáng)制轉(zhuǎn)換 Cat petx = (Cat)pet 。 這是動(dòng)態(tài)綁定或后期綁定的過(guò)程,也稱(chēng)為多態(tài)。

實(shí)際上,對(duì)象在被new出來(lái)后,它所涉及到的方法都放在code segment內(nèi)存區(qū)中的一個(gè)方法列表中,這個(gè)列表中包含了子類(lèi)、父類(lèi)的方法,只不過(guò)有些時(shí)候不可見(jiàn)的方法無(wú)法去調(diào)用。當(dāng)執(zhí)行程序時(shí),內(nèi)部的機(jī)制可以從方法列表中搜索出最符合環(huán)境的方法并執(zhí)行它。

實(shí)現(xiàn)多態(tài)的技術(shù)的關(guān)鍵點(diǎn)在于:

(1). 定義一個(gè)父類(lèi)引用f,并將其指向子類(lèi)對(duì)象,即進(jìn)行向上轉(zhuǎn)型 ;

(2). 重寫(xiě)父類(lèi)的方法,并使用父類(lèi)引用f去引用這個(gè)方法。這樣就可以面向父類(lèi)進(jìn)行編程 。

正如上面的示例中,將pet定義為Animal類(lèi)而非具體的子類(lèi),并在方法中調(diào)用pet.sing()。如此依賴(lài),就無(wú)需考慮pet到底是Cat/Dog,在進(jìn)行功能擴(kuò)展添加Bird類(lèi)時(shí),完全不用再修改Lady類(lèi)的這段代碼。

再例如,父類(lèi)Animal,子類(lèi)Dog,方法sing()。

class Animal {public void sing(A);}
class Dog extends Animal {public void sing(B);}

public class Test {
 Animal a = new Dog(); //父類(lèi)引用變量a指向子對(duì)象Dog,此時(shí)將向上轉(zhuǎn)型
 a.sing();  //使用父類(lèi)引用變量a引用被重寫(xiě)的方法sing(),執(zhí)行時(shí)將動(dòng)態(tài)綁定到Dog的sing()
}

以上這篇java對(duì)象類(lèi)型轉(zhuǎn)換和多態(tài)性(實(shí)例講解)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java 自定義注解的魅力

    Java 自定義注解的魅力

    這篇文章主要介紹了Java 自定義注解的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-03-03
  • 利用java實(shí)現(xiàn)二維碼和背景圖的合并

    利用java實(shí)現(xiàn)二維碼和背景圖的合并

    本文介紹如何使用java代碼將自動(dòng)生成的二維碼放入背景模板中,對(duì)于java學(xué)習(xí)者或許有幫助,一起來(lái)看看。
    2016-07-07
  • SpringSecurity拋出異常但AccessDeniedHandler不生效的解決

    SpringSecurity拋出異常但AccessDeniedHandler不生效的解決

    本文主要介紹了SpringSecurity拋出異常但AccessDeniedHandler不生效的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • mybatis-plus批量更新太慢該如何解決詳解

    mybatis-plus批量更新太慢該如何解決詳解

    這篇文章主要給大家介紹了關(guān)于mybatis-plus批量更新太慢該如何解決的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Spring?Boot解決循環(huán)依賴(lài)的過(guò)程詳細(xì)記錄

    Spring?Boot解決循環(huán)依賴(lài)的過(guò)程詳細(xì)記錄

    這篇文章主要介紹了Spring?Boot解決循環(huán)依賴(lài)的過(guò)程,Spring框架通過(guò)三級(jí)緩存機(jī)制解決循環(huán)依賴(lài)問(wèn)題,分別為singletonObjects、earlySingletonObjects和singletonFactories,需要的朋友可以參考下
    2024-09-09
  • java中javamail發(fā)送帶附件的郵件實(shí)現(xiàn)方法

    java中javamail發(fā)送帶附件的郵件實(shí)現(xiàn)方法

    這篇文章主要介紹了java中javamail發(fā)送帶附件的郵件實(shí)現(xiàn)方法,較為詳細(xì)的分析了JavaMail發(fā)送郵件的用法,是非常實(shí)用的技巧,需要的朋友可以參考下
    2015-01-01
  • spring接口通過(guò)配置支持返回多種格式(xml,json,html,excel)

    spring接口通過(guò)配置支持返回多種格式(xml,json,html,excel)

    這篇文章主要給大家介紹了關(guān)于spring接口如何通過(guò)配置支持返回多種格式(xml,json,html,excel)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • Java 停止線程需要注意的地方

    Java 停止線程需要注意的地方

    這篇文章主要介紹了Java 停止線程需要注意的地方,幫助大家更好的理解和學(xué)習(xí)Java線程的相關(guān)資料,感興趣的朋友可以了解下
    2020-09-09
  • 如何設(shè)置Spring Boot測(cè)試時(shí)的日志級(jí)別

    如何設(shè)置Spring Boot測(cè)試時(shí)的日志級(jí)別

    Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程。該框架使用了特定的方式來(lái)進(jìn)行配置,從而使開(kāi)發(fā)人員不再需要定義樣板化的配置。下面我們來(lái)一起學(xué)習(xí)一下吧
    2019-06-06
  • 兩種實(shí)現(xiàn)Java類(lèi)隔離加載的方法

    兩種實(shí)現(xiàn)Java類(lèi)隔離加載的方法

    這篇文章主要介紹了兩種實(shí)現(xiàn)Java類(lèi)隔離加載的方法,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-02-02

最新評(píng)論

潜江市| 平遥县| 嵊州市| 麻江县| 大厂| 安阳市| 修水县| 民县| 绥棱县| 山丹县| 云安县| 聂拉木县| 和政县| 芜湖市| 阜平县| 延津县| 兰坪| 忻州市| 平罗县| 九寨沟县| 河池市| 丰镇市| 行唐县| 家居| 乐陵市| 句容市| 孟村| 普兰县| 玉林市| 高州市| 大厂| 新安县| 新河县| 新泰市| 谢通门县| 上蔡县| 新兴县| 谷城县| 抚顺市| 彭泽县| 铜川市|