學習筆記,僅供參考
文章目錄
- 面向對象
- 多态
- 多态向上轉型和向下轉型
- 多态的好處和弊端
面向對象
多态
多态向上轉型和向下轉型
我們首先通過以下代碼複習一下自動類型提升和強制類型轉換:
class BunnyAnimal0602 {
public static void main(String[] args) {
int i = 10;
byte b = 20;
i = b; //自動類型提升
b = (byte)i; //強制類型轉換
}
}
由此,我們引出多态中的向上轉型和向下轉型:
class BunnyAnimal0602 {
public static void main(String[] args) {
Father f = new Son();
f.method();
}
}
class Father {
int num = 10;
public void print() {
System.out.println("Print Father");
}
}
class Son extends Father {
int num = 20;
public void print() {
System.out.println("Print Son");
}
public static void method() {
System.out.println("Method Son");
}
}
報錯資訊:
---------- javac ----------
BunnyAnimal0602.java:4: 錯誤: 找不到符号
f.method();
^
符号: 方法 method()
位置: 類型為Father的變量 f
1 個錯誤
Output completed (2 sec consumed) - Normal Termination
父類引用指向子類對象就是向上轉型。同時,我們看到在上述代碼中,由于父類中沒有method方法,是以編譯時報錯。
下面我們通過向下轉型,去調用子類中的method方法:
class BunnyAnimal0602 {
public static void main(String[] args) {
Father f = new Son();
System.out.println(f.num);
Son s = (Son)f;
s.method();
}
}
class Father {
int num = 10;
public void print() {
System.out.println("Print Father");
}
}
class Son extends Father {
int num = 20;
public void print() {
System.out.println("Print Son");
}
public static void method() {
System.out.println("Method Son");
}
}
輸出:
10
Method Son
記憶體圖:
多态的好處和弊端
- 多态的好處
- 提高代碼的維護性
- 提高代碼的擴充性
- 多态的弊端
- 不能使用子類特有的屬性和行為
- 舉個例子(多态的好處)
class AnimalBunnyCat {
public static void main(String[] args) {
method(new Bunny());
method(new Cat());
}
public static void method(Animal a) {
a.eat();
}
}
class Animal {
public void eat() {
System.out.println("動物吃飯");
}
}
class Bunny extends Animal {
public void eat() {
System.out.println("兔子吃胡蘿蔔");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("貓吃魚");
}
}
輸出:
兔子吃胡蘿蔔
貓吃魚
- 舉個例子(強轉)
基于上面的代碼,我們給method增加一些功能,如果輸入參數是Cat的對象,則增加Cat特有的功能,如果輸入參數是Bunny的對象,則增加Bunny特有的功能:
class AnimalBunnyCat {
public static void main(String[] args) {
method(new Bunny());
method(new Cat());
}
public static void method(Animal a) {
if (a instanceof Bunny) {
Bunny b = (Bunny)a;
b.eat();
b.play();
} else if (a instanceof Cat) {
Cat c = (Cat)a;
c.eat();
c.sleep();
} else {
a.eat();
}
}
}
class Animal {
public void eat() {
System.out.println("動物吃飯");
}
}
class Bunny extends Animal {
public void eat() {
System.out.println("兔子吃胡蘿蔔");
}
public void play() {
System.out.println("兔子玩耳朵");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("貓吃魚");
}
public void sleep() {
System.out.println("貓睡覺");
}
}
輸出:
兔子吃胡蘿蔔
兔子玩耳朵
貓吃魚
貓睡覺
關鍵字
instanceof
為判斷前面的引用是否是後面的資料類型。如果沒有經過
instanceof
判斷,我們可能會把Cat強制轉換為Bunny這樣就會出現類型轉換異常
ClassCastException