一、前言
這篇講下三大特性之一的多態,可以通俗得去理解,多種形態,多種姿態。。。
那么在面向對象的程序設計中,多態是 指什么?
Java引用變量有兩個類型;一個是編譯類型,一個是運行時類型。編譯時類型由聲明該變量時使用的類型決定,運行時類型由實際賦給該變量的對象決定.如果編譯類型和運行時類型不一致,就可能出現所謂的多態(Polymorphism)
“多形性”(Polymorphism)從另一個角度將接口從具體的實施細節中分離出來,亦即實現了“是什么”與“怎樣做”兩個模塊的分離。利用多形性的概念,代碼的組織以及可讀性均能獲得改善。此外,還能創建“易於擴展”的程序。無論在項目的創建過程中,還是在需要加入新特性的時候,它們都可以方便地“成長”。——ThinkinJava
直接網易百科-Polymorphism

二、發生的條件
- 繼承。多態發生一定要子類和父類之間。
- 覆蓋。子類覆蓋父類的方法
- 聲明的變量類型是父類,但是實際指向的是子類。程序中的new后面就是子類
//f4變量是子類類型,指向子類實例
Triangle f4 = new Triangle();
三、多態包含(或者說體現在)兩個方面:
- 首先是同一個方法,不同的實現效果,就具體的方法是怎么實現的,是可以不同的。就是方法的多態性。
吃蘋果方法,可以剝皮吃,也可以不剝皮吃,甚至是榨蘋果汁喝。
規范講這種就是可以通過重載和覆寫來實現
- 重載:同一個方法名稱,因為不同的參數類型和個數,因此可以達到不同的效果。
- 覆寫:同一個方法,根據實例化的子類對象不同,最后的效果和實現功能不一樣。
-
對象的多態性
引用類型轉換也是通過小括號運算符實現,類型轉換有兩個方向:將父類引用類型
變量轉換為子類類型,這種轉換稱為向下轉型(downcast);將子類引用類型變量轉換為
父類類型,這種轉換稱為向上轉型(upcast)。向下轉型需要強制轉換,而向上轉型是自
動的。
- 向上轉型:子類對象變為父類
- 向下轉型:父類對象變為子類
四、示例
- 簡單的示例多態,代碼里面的@Override是偽代碼,表示方法重寫。一般你重寫正確了,IDE會自動加上去的。也是一種驗證方法。
package music.daima.ebook;
class Figure{
//繪制幾何圖形方法
public void onDraw() {
System.out.println("繪制Figure...");
}
}
class Ellipse extends Figure{
@Override
public void onDraw() {
System.out.println("繪制橢圓形");
}
}
class Triangle extends Figure {
// 繪制幾何圖形方法
@Override
public void onDraw() {
System.out.println("繪制三角形...");
} }
public class PolymorphismEasy {
public static void main(String[] args) {
// f1變量是父類類型,指向父類實例
Figure f1 = new Figure();
f1.onDraw();
//f2變量是父類類型,指向子類實例,發生多態
Figure f2 = new Triangle();
f2.onDraw();
//f3變量是父類類型,指向子類實例,發生多態
Figure f3 = new Ellipse();
f3.onDraw();
//f4變量是子類類型,指向子類實例
Triangle f4 = new Triangle( );
f4.onDraw();
}
}
//output:
繪制Figure...
繪制三角形...
繪制橢圓形
繪制三角形...
- 不能覆蓋private方法
package music.daima.ebook;
public class PolymorphismFugai {
private void p(){//if public...就可以覆蓋
System.out.println("1");
}
public static void main(String[] args) {
PolymorphismFugai s = new jicheng();
s.p();//將輸出的是上面的1而不是我們想要的jicheng類中的方法
}
}
class jicheng extends PolymorphismFugai{
public void p(){
System.out.println("2");
}
}
//output:1
- Static靜態方法與多態的關系
package music.daima.ebook;
//這一篇是用來研究靜態方法與多態的
class A {
public static String get(){//定義一個方法
return "A is base";
}
}
//繼承A
class B extends A {
public static String get(){//同樣的方法
return "B is not base";
}
}
public class StaticUpcast {
public static void main(String[] args) {
A a = new B();//upcast 向上轉型
System.out.println(a.get());
}
}
//output:
//A is base
//從這里發現靜態方法是與類相關聯的,不是與單個對象關聯的,不能覆蓋掉
感謝閱讀
才疏學淺,有不對的地方歡迎指教!