(多態(tài))轉(zhuǎn)型問題其實(shí)并不復(fù)雜计技,只要記住一句話:父類引用指向子類對(duì)象忠蝗。
什么叫父類引用指向子類對(duì)象基茵,且聽我慢慢道來.從2個(gè)名詞開始說起:向上轉(zhuǎn)型(upcasting) 膛堤、向下轉(zhuǎn)型(downcasting).
舉個(gè)例子:有2個(gè)類手趣,F(xiàn)ather是父類,Son類繼承自Father肥荔。
Father f1 = new Son(); // 這就叫 upcasting (向上轉(zhuǎn)型)
// 現(xiàn)在f1引用指向一個(gè)Son對(duì)象
Son s1 = (Son)f1; // 這就叫 downcasting (向下轉(zhuǎn)型)
// 現(xiàn)在f1還是指向Son對(duì)象
第2個(gè)例子:
Father f2 = new Father();
Son s2 = (Son)f2; // 出錯(cuò)绿渣,子類引用不能指向父類對(duì)象
你或許會(huì)問,第1個(gè)例子中:Son s1 = (Son)f1;問什么 是正確的呢燕耿。
很簡單因?yàn)閒1指向一個(gè)子類對(duì)象中符,F(xiàn)ather f1 = new Son(); 子類s1引用當(dāng)然可以指向子類對(duì)象了。
而f2 被傳給了一個(gè)Father對(duì)象誉帅,F(xiàn)ather f2 = new Father()淀散;子類s1引用不能指向父類對(duì)象谭期。
實(shí)例
- 向上轉(zhuǎn)型:子類引用的對(duì)象轉(zhuǎn)換為父類類型稱為向上轉(zhuǎn)型。通俗地說就是是將子類對(duì)象轉(zhuǎn)為父類對(duì)象吧凉。此處父類對(duì)象可以是接口
- 向上轉(zhuǎn)型時(shí)隧出,父類指向子類引用對(duì)象會(huì)遺失除與父類對(duì)象共有的其他方法,也就是在轉(zhuǎn)型過程中阀捅,子類的新有的方法都會(huì)遺失掉胀瞪,在編譯時(shí),系統(tǒng)會(huì)提供找不到方法的錯(cuò)誤
向下轉(zhuǎn)型:父類引用的對(duì)象轉(zhuǎn)換為子類類型稱為向下轉(zhuǎn)型饲鄙。
父類
package testP.test;
class Person {
public void eat(){
System.out.println("Person eatting...");
}
public void sleep() {
System.out.println("Person sleep...");
}
}
向上轉(zhuǎn)型
package testP.test;
public class son extends Person {
public void eat() {
System.out.println("son eatting...");
}
public void fly() {
System.out.println("son fly...");
}
public static void main(String[] args) {
Person person = new son();
person.eat(); // 調(diào)用的是son里面的eat方法凄诞,son重寫了Person父類的方法
person.sleep(); //調(diào)用的是父類person的方法
person.fly(); //報(bào)錯(cuò)了,丟失了son類的fly方法
}
}
向下轉(zhuǎn)型
在向下轉(zhuǎn)型過程中忍级,分為兩種情況:
情況一:如果父類引用的對(duì)象如果引用的是指向的子類對(duì)象帆谍,那么在向下轉(zhuǎn)型的過程中是安全的。也就是編譯是不會(huì)出錯(cuò)誤的轴咱。
情況二:如果父類引用的對(duì)象是父類本身汛蝙,那么在向下轉(zhuǎn)型的過程中是不安全的,編譯不會(huì)出錯(cuò)朴肺,但是運(yùn)行時(shí)會(huì)出現(xiàn)java.lang.ClassCastException錯(cuò)誤窖剑。它可以使用instanceof來避免出錯(cuò)此類錯(cuò)誤
- 安全不報(bào)錯(cuò)
package testP.test;
public class son extends Person {
public void eat() {
System.out.println("son eatting...");
}
public void fly() {
System.out.println("son fly...");
}
public static void main(String[] args) {
Person person = new son(); // 向上轉(zhuǎn)型
son s = (son)person; //向下轉(zhuǎn)型,編譯和運(yùn)行皆不會(huì)出錯(cuò)
s.fly();
s.eat();
s.sleep();
}
}
- 編譯器報(bào)錯(cuò)
package testP.test;
public class son extends Person {
public void eat() {
System.out.println("son eatting...");
}
public void fly() {
System.out.println("son fly...");
}
public static void main(String[] args) {
Person upPerson = new Person();
son so = (son)upPerson; // 向下轉(zhuǎn)型 編譯器報(bào)錯(cuò)了
so.fly();
}
}