多態指的是同一個方法調用,由於對象不同可能會有不同的行為。現實生活中,同一個方法,具體實現會完全不同。 比如:同樣是調用人的“休息”方法,張三是睡覺,李四是旅游,高淇老師是敲代碼,數學教授是做數學題; 同樣是調用人“吃飯”的方法,中國人用筷子吃飯,英國人用刀叉吃飯,印度人用手吃飯。
多態的要點:
1. 多態是方法的多態,不是屬性的多態(多態與屬性無關)。
2. 多態的存在要有3個必要條件:繼承,方法重寫,父類引用指向子類對象。
3. 父類引用指向子類對象后,用該父類引用調用子類重寫的方法,此時多態就出現了。
【示例5-12】多態和類型轉換測試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
class
Animal {
public
void
shout() {
System.out.println(
"叫了一聲!"
);
}
}
class
Dog
extends
Animal {
public
void
shout() {
System.out.println(
"旺旺旺!"
);
}
public
void
seeDoor() {
System.out.println(
"看門中...."
);
}
}
class
Cat
extends
Animal {
public
void
shout() {
System.out.println(
"喵喵喵喵!"
);
}
}
public
class
TestPolym {
public
static
void
main(String[] args) {
Animal a1 =
new
Cat();
// 向上可以自動轉型
//傳的具體是哪一個類就調用哪一個類的方法。大大提高了程序的可擴展性。
animalCry(a1);
Animal a2 =
new
Dog();
animalCry(a2);
//a2為編譯類型,Dog對象才是運行時類型。
//編寫程序時,如果想調用運行時類型的方法,只能進行強制類型轉換。
// 否則通不過編譯器的檢查。
Dog dog = (Dog)a2;
//向下需要強制類型轉換
dog.seeDoor();
}
// 有了多態,只需要讓增加的這個類繼承Animal類就可以了。
static
void
animalCry(Animal a) {
a.shout();
}
/* 如果沒有多態,我們這里需要寫很多重載的方法。
* 每增加一種動物,就需要重載一種動物的喊叫方法。非常麻煩。
static void animalCry(Dog d) {
d.shout();
}
static void animalCry(Cat c) {
c.shout();
}*/
}
|
執行結果如圖5-17所示:
圖5-17 示例5-12運行效果圖
示例5-12給大家展示了多態最為多見的一種用法,即父類引用做方法的形參,實參可以是任意的子類對象,可以通過不同的子類對象實現不同的行為方式。
由此,我們可以看出多態的主要優勢是提高了代碼的可擴展性,符合開閉原則。但是多態也有弊端,就是無法調用子類特有的功能,比如,我不能使用父類的引用變量調用Dog類特有的seeDoor()方法。
那如果我們就想使用子類特有的功能行不行呢?行!這就是我們下一章節所講的內容:對象的轉型。