概念
多态主要指同一種事物表現出來的多種形态。如:
• 飲料:可樂、雪碧、紅牛、脈動、...
• 寵物:貓、狗、鳥、小強、魚、...
• 人:學生、教師、勞工、保安、...
• 圖形:矩形、圓形、梯形、三角形、...
文法格式
父類類型 引用變量名 = new 子類類型(); 如:
Shape sr = new Rect();
sr.show();
特點
1.當父類類型的引用指向子類類型的對象時,父類類型的引用可以直接調 用父類獨有的方法。
2.當父類類型的引用指向子類類型的對象時,父類類型的引用不可以直接 調用子類獨有的方法。
3.對于父子類都有的非靜态方法來說,編譯階段調用父類版本,運作階段 調用子類重寫的版本(動态綁定)。
4.對于父子類都有的靜态方法來說,編譯和運作階段都調用父類版本。
demo code:
public class Shape {
private int x;
private int y;
public Shape() {
}
public Shape(int x, int y) {
setX(x);
setY(y);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void show() {
System.out.println("橫坐标:" + getX() + ",縱坐标:" + getY());
}
// 自定義靜态方法
public static void test() {
System.out.println("Shape類中的靜态方法!");
}
}
public class Rect extends Shape {
private int len;
private int wid;
public Rect() {
}
public Rect(int x, int y, int len, int wid) {
super(x, y);
setLen(len);
setWid(wid);
}
public int getLen() {
return len;
}
public void setLen(int len) {
if(len > 0) {
this.len = len;
} else {
System.out.println("長度不合理哦!!!");
}
}
public int getWid() {
return wid;
}
public void setWid(int wid) {
if (wid > 0) {
this.wid = wid;
} else {
System.out.println("寬度不合理哦!!!");
}
}
@Override
public void show() {
super.show();
System.out.println("長度是:" + getLen() + ",寬度是:" + getWid());
}
// 自定義靜态方法
public static void test() {
System.out.println("---Rect類中的靜态方法!");
}
}
public class ShapeRectTest {
public static void main(String[] args) {
Shape sr = new Rect(7, 8, 9, 10);
// 當Rect類中沒有重寫show方法時,下面調用Shape類中的show方法
// 當Rect類中重寫show方法後,下面的代碼在編譯階段調用Shape類的方法,在運作階段調用Rect類中的show方法
sr.show(); // 7 8 9 10
System.out.println("1.當父類類型的引用指向子類類型的對象時,父類類型的引用可以直接調 用父類獨有的方法。2.當父類類型的引用指向子類類型的對象時,父類類型的引用不可以直接 調用子類獨有的方法。");
int ia = sr.getX();
System.out.println("擷取到的橫坐标是:" + ia); // 7
//sr.getLen(); //error Shape類中找不到getLen方法,也就是還在Shape類中查找
// 使用父類類型的引用調用子類獨有方法的方式
// 相當于從Shape類型到Rect類型的轉換,也就是父類到子類的轉換 大到小的轉換 強制類型轉換
int ib = ((Rect) sr).getLen();
System.out.println("擷取到的長度是:" + ib); // 9
// 希望将Shape類型強制轉換為Circle類型,下面沒有報錯
// Circle c1 = (Circle)sr; // 編譯ok,但運作階段發生 ClassCastException類型轉換異常,Rect類無Circle
// 在強制類型轉換之前應該使用instanceof進行類型的判斷
// 判斷sr指向堆區記憶體中的對象是否為Circle類型,若是則傳回true,否則傳回false
if(sr instanceof Circle) {
System.out.println("可以放心地轉換了!");
Circle c1 = (Circle)sr;
} else {
System.out.println("強轉有風險,操作需謹慎!");
}
}
}
引用資料類型之間的轉換
1.引用資料類型之間的轉換方式有兩種:自動類型轉換 和 強制類型轉換。
2.自動類型轉換主要指小類型向大類型的轉換,也就是子類轉為父類,也叫做向上轉型。
3.強制類型轉換主要指大類型向小類型的轉換,也就是父類轉為子類,也 叫做向下轉型或顯式類型轉換。
5.若強轉的目标類型并不是該引用真正指向的資料類型時則編譯通過,運作階段發生類型轉換異常。