1. 程式人生 > >JAVA的多型特性詳解

JAVA的多型特性詳解

 * 多型:    父類的 引用變數 指向了子類的物件              或者  *         介面的 引用變數 指向了介面實現類物件  * 多型前提:必須存在 繼承或者 實現關係  * 多型要注意的細節:  *     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("張三");
	}
}