天天看點

JAVA多态

概念

多态主要指同一種事物表現出來的多種形态。如:

• 飲料:可樂、雪碧、紅牛、脈動、...

• 寵物:貓、狗、鳥、小強、魚、...

• 人:學生、教師、勞工、保安、...

• 圖形:矩形、圓形、梯形、三角形、...

文法格式

父類類型 引用變量名 = 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.若強轉的目标類型并不是該引用真正指向的資料類型時則編譯通過,運作階段發生類型轉換異常。