JAVA的多型特性詳解
阿新 • • 發佈:2018-12-15
* 多型: 父類的 引用變數 指向了子類的物件
或者
* 介面的 引用變數 指向了介面實現類物件
* 多型前提:必須存在 繼承或者 實現關係
* 多型要注意的細節:
* 1.多型情況下,子父類 存在 同名的成員變數(包括 非靜態和 靜態),預設 訪問父類的成員變數
* 2.多型情況下,子父類 存在 同名的非靜態函式時,預設的是 子類的成員函式
* 3.多型情況下,子父類 存在 同名的靜態函式時,預設訪問的父類的成員函式
* 4.多型情況下,不能訪問 子類 特有的成員
* 總結: 對於 同名 子父類的成員,只有 非靜態的成員方法,訪問的是 子類 ,其他的訪問的都是父類
/* * 需求:定義一個圖形,矩形,圓形 三個雷,所有的圖形都具備計算 面積和周長的方法 * * 要求: * 1.定義一個方法 可以接受 任意型別的圖形物件, * 在該方法內部 呼叫 圖形的周長和麵積的方法 * * 2.定義一個方法 ,可以返回 任意型別的圖形物件 * * */ abstract class Shape{ public abstract double getArea(); public abstract double getLength(); } //單繼承: java是單繼承的,一個類 最多 只能有一個 直接父類 //(一種事物 只能夠 是屬於 唯一的另一種事物) class Rect extends Shape{ double width; double height; public Rect(double width, double height) { this.width = width; this.height = height; } @Override public double getArea() { return width*height; } @Override public double getLength() { return 2*(width+height); } } class Circle extends Shape{ public static final double PI = 3.14; double r; public Circle(double r) { super(); this.r = r; } @Override public double getArea() { // TODO Auto-generated method stub return PI*r*r; } @Override public double getLength() { // TODO Auto-generated method stub return 2*PI*r; } } public class Demo1 { public static void main(String[] args) { Rect r = new Rect(2.0, 3.0); Circle c = new Circle(3.0); //定義一個方法 print。具備多種過載方式,列印傳進去的各種圖形的周長和麵積 //print(r); //print(c); //但是 ,我們希望在一個方法中 實現 (使用多型) Shape s1 = new Rect(3.0, 4.0); Shape s2 = new Circle(4.0); print(s1); print(s2); //Shape s3 = getShape(1); //Shape s4 = getShape(-1); //強制型別轉換 Rect r2 = (Rect)getShape(1); Circle c2 = (Circle)getShape(-1); } //多型的用法: //父類型別 可以 作為 方法的返回值,具體返回的型別可以是 任意 子類型別 //定義一個方法,可以返回任意型別的圖形物件 public static Shape getShape(int i){ //通過i的 值來返回 if(i>0){ return new Rect(4.0, 5.0); }else{ return new Circle(4.0); } } //多型的作用: //父類可以作為方法的引數型別,具體 傳進方法的引數 可以是 任意 子類型別 //定義一個方法,可以接受 任意型別的圖形物件 private static void print(Shape s) { /* 傳進去的 s 是一個 父類的顯式型別(編譯時型別), 如何知道 到底是 什麼 實際型別(執行時型別)? */ String shapeName = ""; if(s instanceof Rect){ shapeName = "矩形"; }else if(s instanceof Circle){ shapeName = "圓形"; } System.out.println(shapeName+"的面積:"+s.getArea()); System.out.println(shapeName+"的周長:"+s.getLength()); } /* private static void print(Circle c) { System.out.println("圓形的周長為:"+c.getLength()); System.out.println("圓形的面積為:"+c.getArea()); } private static void print(Rect r) { System.out.println("矩形的周長為"+r.getLength()); System.out.println("矩形的面積為"+r.getArea()); }*/ }
多型情況下,不能訪問子類特有的成員 多型 情況下,如果需要 呼叫到子類 特有的成員,那麼需要進行 強制型別轉換 * 基本資料型別: * 小資料型別->大資料型別: 自動型別轉換 * 大資料型別->小資料型別: 強制型別轉換 * 引用資料型別轉換 * 子類資料型別->父類資料型別: 自動型別轉換 * 父類資料型別->子類資料型別: 強制型別轉換 * ClassCastException:強制型別轉換異常
* 在轉換之前 一般 使用 instanceof關鍵字 先判斷
class A{
int a = 10;
}
class B extends A{
int b = 20;
}
class C extends A{
}
public class Demo2 {
public static void main(String[] args) {
A a = new B(); //自動型別轉換
//將 父類 的 型別 轉換為 子類的型別(大轉小:強轉)
B b = (B) a; //強制型別轉換
//C c = (C) a; //ClassCastException
System.out.println("a屬於 B型別:"+(a instanceof B));
System.out.println("a屬於 C型別:"+(a instanceof C));
System.out.println(b.b);
}
}
實現關係下的多型:介面的引用 型別變數 指向了 介面實現類的物件 * 介面中的方法 全部 是 非靜態。多型情況下, 子父類 存在同名的非靜態函式時, * 預設是訪問子類的非靜態函式
interface Dao{
/*
* 介面中的方法 全部 是 非靜態。多型情況下, 子父類 存在同名的非靜態函式時,
* 預設是訪問子類的非靜態函式
*
* */
void add(String user);
}
class UserDao implements Dao{
@Override
public void add(String user) {
// TODO Auto-generated method stub
System.out.println("新增使用者"+user+"成功");
}
}
public class Demo3 {
public static void main(String[] args) {
Dao d = new UserDao(); //實現關係下的多型
d.add("張三");
}
}