Java基礎——面向物件(五)多型
阿新 • • 發佈:2019-01-10
一、概述
物件的多型性
class 動物
{}
class 貓 extends 動物
{}
class 狗 extends 動物
{}
class Demo{
public static void main(String[] args){
貓 x = new 貓();
動物 y = new 貓();//表象:父類建立物件指向了子類,體現了多型
}
}
貓這類食物既具備貓的形態,又具備動物的形態。這就是多型性。
簡單說:就是一個物件對應著不同型別
二、優點
提高了程式碼的擴充套件性,前期定義的程式碼可以使用後期的內容。
abstract class Animal { abstract void eat(); } class Dog extends Animal { void eat() { System.out.println("啃骨頭"); } void lookHome() { System.out.println("看家"); } } class Cat extends Animal { void eat() { System.out.println("吃魚"); } void catchMouse() { System.out.println("抓老鼠"); } } class Pig extends Animal { void eat() { System.out.println("飼料"); } void gongDi() { System.out.println("拱地"); } } class DuoTaiDemo { public static void main(String[] args) { // Cat c = new Cat(); // c.eat(); // c.catchMouse(); Animal a = new Cat(); //自動型別提升,貓物件提升了動物型別。但是特有功能無法s訪問。 //作用就是限制對特有功能的訪問。 //專業講:向上轉型。將子型別隱藏。就不用使用子類的特有方法。 // a.eat(); //如果還想用具體動物貓的特有功能。 //你可以將該物件進行向下轉型。 // Cat c = (Cat)a;//向下轉型的目的是為了使用子類中的特有方法。 // c.eat(); // c.catchMouse(); // 注意:對於轉型,自始自終都是子類物件在做著型別的變化。 // Animal a1 = new Dog(); // Cat c1 = (Cat)a1;//ClassCastException /* Cat c = new Cat(); // Dog d = new Dog(); // c.eat(); method(c); // method(d); // method(new Pig()); */ method(new Dog()); } public static void method(Animal a)//Animal a = new Dog(); { a.eat(); if(a instanceof Cat)//instanceof:用於判斷物件的具體型別。只能用於引用資料型別判斷 // //通常在向下轉型前用於健壯性的判斷。 { Cat c = (Cat)a; c.catchMouse(); } else if(a instanceof Dog) { Dog d = (Dog)a; d.lookHome(); } else { } } /* public static void method(Cat c) { c.eat(); } public static void method(Dog d) { } */ }
三、多型的前提&弊端
1.弊端:前期定義的內容不能使用(呼叫)後期子類的特有內容。 定義了animal不能使用貓的catchMouse
2.前提:
- 必須有關係,繼承,實現。
- 必須有覆蓋
四、轉型
1.向上轉型:作用就是限制對特有功能的訪問。
專業講:向上轉型。將子型別隱藏。就不用使用子類的特有方法。
2.向下轉型:向下轉型的目的是為了使用子類中的特有方法。
注意:對於轉型,自始自終都是子類物件在做著型別的變化。
3.型別判斷instanceof
用於判斷物件的具體型別。
if(a instanceof Cat)//instanceof:用於判斷物件的具體型別。只能用於引用資料型別判斷
//通常在向下轉型前用於健壯性的判斷。
{
Cat c = (Cat)a;
c.catchMouse();
}
else if(a instanceof Dog)
{
Dog d = (Dog)a;
d.lookHome();
}
五、多型後成員變化特點(重點)
1.成員變數。
編譯時,參考引用型變數所屬的類中是否有呼叫的成員變數?有,編譯通過;沒有,編譯失敗。
執行時,參考引用型變數所屬的類中是否有呼叫的成員變數?並執行該所屬類中的成員變數。
簡單說,就是編譯和執行都參考左邊。
2.成員函式。
編譯時:參考引用型變數所屬的類中的是否有呼叫的函式。有,編譯通過,沒有,編譯失敗。
執行時:參考的是物件所屬的類中是否有呼叫的函式。
簡單說:編譯看左邊,執行看右邊。
因為成員函式存在覆蓋特性。
3.靜態函式。
編譯時:參考引用型變數所屬的類中的是否有呼叫的靜態方法。
執行時:參考引用型變數所屬的類中的是否有呼叫的靜態方法。
簡單說,編譯和執行都看左邊。
其實對於靜態方法,是不需要物件的。直接用類名呼叫即可。