詳細講述Java中的對象轉型
向上轉型:子類對象轉為父類,父類可以是接口。公式:Father f = new Son();Father是父類或接口,son是子類。
向下轉型:父類對象轉為子類。公式:Son s = (Son)f;

我們將形參設為父類Animal類型,當執(zhí)行test.f(c)時,內存情況如下圖:

c作為Cat類型傳入,Animal a作為形參,相當于執(zhí)行了Animal a = new Cat(),這時a和c同時指向Cat對象,但此時a不能訪問Cat類擴展的數(shù)據(jù)成員,所以再將a強轉成Cat類型即可。如果不存在這樣的轉型機制,則針對貓和狗我們還要分別寫兩個函數(shù)f(Cat c)和f(Dog d)。但其實上圖程序的可擴展性也不是最好的。我們還可以利用動態(tài)綁定(即多態(tài))將擴展性進一步提升。多態(tài)機制的三個前提分別是:
(1)要有繼承
(2)要重寫,即子類對父類中某些方法進行重新定義
(3)要向上轉型,用父類引用指向子類對象。
下面來看一個例子:
class Animal { private String name; /**
* 在Animal類自定義的構造方法
* @param name */
Animal(String name) { this.name = name;
} /**
* 在Animal類里面自定義一個方法enjoy */
public void enjoy() {
System.out.println("動物的叫聲……");
}
}class Cat extends Animal { private String eyesColor; /**
* 在子類Cat里面定義Cat類的構造方法
* @param n
* @param c */
Cat(String n, String c) { /**
* 在構造方法的實現(xiàn)里面首先使用super調用父類Animal的構造方法Animal(String name)。
* 把子類對象里面的父類對象先造出來。 */
super(n);
eyesColor = c;
} /**
* 子類Cat對從父類Animal繼承下來的enjoy方法不滿意,在這里重寫了enjoy方法。 */
public void enjoy() {
System.out.println("我養(yǎng)的貓高興地叫了一聲……");
}
}/**
* 子類Dog從父類Animal繼承下來,Dog類擁有了Animal類所有的屬性和方法。
* @author gacl
* */class Dog extends Animal { /**
* 在子類Dog里面定義自己的私有成員變量 */
private String furColor; /**
* 在子類Dog里面定義Dog類的構造方法
* @param n
* @param c */
Dog(String n, String c) { /**
* 在構造方法的實現(xiàn)里面首先使用super調用父類Animal的構造方法Animal(String name)。
* 把子類對象里面的父類對象先造出來。 */
super(n);
furColor = c;
} /**
* 子類Dog對從父類Animal繼承下來的enjoy方法不滿意,在這里重寫了enjoy方法。 */
public void enjoy() {
System.out.println("我養(yǎng)的狗高興地叫了一聲……");
}
}/**
* 子類Bird從父類Animal繼承下來,Bird類擁有Animal類所有的屬性和方法
* @author gacl
* */class Bird extends Animal { /**
* 在子類Bird里面定義Bird類的構造方法 */
Bird() { /**
* 在構造方法的實現(xiàn)里面首先使用super調用父類Animal的構造方法Animal(String name)。
* 把子類對象里面的父類對象先造出來。 */
super("bird");
} /**
* 子類Bird對從父類Animal繼承下來的enjoy方法不滿意,在這里重寫了enjoy方法。 */
public void enjoy() {
System.out.println("我養(yǎng)的鳥高興地叫了一聲……");
}
}/**
* 定義一個類Lady(女士)
* @author gacl
* */class Lady { /**
* 定義Lady類的私有成員變量name和pet */
private String name; private Animal pet; /**
* 在Lady類里面定義自己的構造方法Lady(),
* 這個構造方法有兩個參數(shù),分別為String類型的name和Animal類型的pet,
* 這里的第二個參數(shù)設置成Animal類型可以給我們的程序帶來最大的靈活性,
* 因為作為養(yǎng)寵物來說,可以養(yǎng)貓,養(yǎng)狗,養(yǎng)鳥,只要是你喜歡的都可以養(yǎng),
* 因此把它設置為父類對象的引用最為靈活。
* 因為這個Animal類型的參數(shù)是父類對象的引用類型,因此當我們傳參數(shù)的時候,
* 可以把這個父類的子類對象傳過去,即傳Dog、Cat和Bird等都可以。
* @param name
* @param pet */
Lady(String name, Animal pet) { this.name = name; this.pet = pet;
} /**
* 在Lady類里面自定義一個方法myPetEnjoy()
* 方法體內是讓Lady對象養(yǎng)的寵物自己調用自己的enjoy()方法發(fā)出自己的叫聲。 */
public void myPetEnjoy() {
pet.enjoy();
}
}public class Jerque { public static void main(String args[]) { /**
* 在堆內存里面new了一只藍貓對象出來,這個藍貓對象里面包含有一個父類對象Animal。 */
Cat c = new Cat("Catname", "blue"); /**
* 在堆內存里面new了一只黑狗對象出來,這個黑狗對象里面包含有一個父類對象Animal。 */
Dog d = new Dog("Dogname", "black"); /**
* 在堆內存里面new了一只小鳥對象出來,這個小鳥對象里面包含有一個父類對象Animal。 */
Bird b = new Bird(); /**
* 在堆內存里面new出來3個小姑娘,名字分別是l1,l2,l3。
* l1養(yǎng)了一只寵物是c(Cat),l2養(yǎng)了一只寵物是d(Dog),l3養(yǎng)了一只寵物是b(Bird)。
* 注意:調用Lady類的構造方法時,傳遞過來的c,d,b是當成Animal來傳遞的,
* 因此使用c,d,b這三個引用對象只能訪問父類Animal里面的enjoy()方法。 */
Lady l1 = new Lady("l1", c);
Lady l2 = new Lady("l2", d);
Lady l3 = new Lady("l3", b); /**
* 這三個小姑娘都調用myPetEnjoy()方法使自己養(yǎng)的寵物高興地叫起來。 */
l1.myPetEnjoy();
l2.myPetEnjoy();
l3.myPetEnjoy();
}
}
上面的例子中,我們發(fā)現(xiàn),如果我們想要加入新的動物,只需定義相應的類繼承Animal,完全不用動任何一處代碼,因為這里運用了面向對象最核心的東西——多態(tài)。與之前的例子不同,雖然我們一直強調當用父類的引用指向子類對象,父類無法訪問子類自己的成員,但是方法與數(shù)據(jù)成員不同,具體調哪一個方法是等到運行時決定的,new出了什么對象就調用相應對象的方法,取決于實際new出的對象而不是指向對象的引用,所以當傳入不同動物類型,mypetEnjoy()就會去執(zhí)行不同的方法

相關文章
RestTemplate發(fā)送請求時Cookie的影響及注意事項說明
這篇文章主要介紹了RestTemplate發(fā)送請求時Cookie的影響及注意事項說明,具有很好的參考價值,希望對大家有所幫助。2023-07-07
Java SE使用數(shù)組實現(xiàn)高速數(shù)字轉換功能
隨著大數(shù)據(jù)時代的到來,數(shù)字轉換功能變得越來越重要,在Java開發(fā)中,數(shù)字轉換功能也是經常用到的,下面我們就來學習一下如何使用Java SE數(shù)組實現(xiàn)高速的數(shù)字轉換功能吧2023-11-11
將一個數(shù)組按照固定大小進行拆分成數(shù)組的方法
下面小編就為大家?guī)硪黄獙⒁粋€數(shù)組按照固定大小進行拆分成數(shù)組的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11

