12-15java面向對象之多態性操作

1.多態性

1.概念

向上轉型(自動完成)

子類轉變成父類

父類  父類對象 子類實例化對象

向下轉型(強制)

父類轉變成子類,必須首先進行向上轉型

子類  子類對象 (子類)父類實例化對象 

2.子類對象向上轉型

//本程序是多態性的測試
class A							//定義類A
{
	public void fun1()			//定義類A的fun1方法
	{
		System.out.println("這是類A的fun1方法");
	}
	public void fun2()
	{
		this.fun1();
	}
}
class B extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類B覆寫的fun1方法");
	}
	public void fun3()
	{
		System.out.println("這是類B的fun3方法");
	}
}
public class  TestPol
{
	public static void main(String[] args) 
	{
		B b = new B();			//定義子類的實例化對象
		A a = b;				//子類對象向上轉型
		a.fun1();				//此方法被子類覆寫了,輸出的是覆寫的
		a.fun2();				//此方法被子類覆寫了,輸出的是覆寫的
	}
}

說明:向上轉型使用方法都是子類覆寫過的方法。

注意:在A中只能看到兩個方法,在B看到三個方法,轉型之後,因爲操作的是父類,所以無法找到子類中定義的新方法。

//本程序是多態性的測試
class A							//定義類A
{
	public void fun1()			//定義類A的fun1方法
	{
		System.out.println("這是類A的fun1方法");
	}
	public void fun2()
	{
		this.fun1();
	}
}
class B extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類B覆寫的fun1方法");
	}
	public void fun3()
	{
		System.out.println("這是類B的fun3方法");
	}
}
public class  TestPol
{
	public static void main(String[] args) 
	{
		B b = new B();			//定義子類的實例化對象
		A a = b;				//子類對象向上轉型
		a.fun1();				//此方法被子類覆寫了,輸出的是覆寫的
		a.fun3();				//新方法
	}
}
錯誤信息提示:

TestPol.java:31: 錯誤找不到符號

                a.fun3();                               //新方法

                 ^

  符號:   方法 fun3()

  位置類型爲A的變量 a

3.父類對象向下轉型

//本程序是多態性的測試
class A							//定義類A
{
	public void fun1()			//定義類A的fun1方法
	{
		System.out.println("這是類A的fun1方法");
	}
	public void fun2()
	{
		this.fun1();
	}
}
class B extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類B覆寫的fun1方法");
	}
	public void fun3()
	{
		System.out.println("這是類B的fun3方法");
	}
}
public class  TestPol
{
	public static void main(String[] args) 
	{
		B b = new B();			//定義子類的實例化對象
		A a = b;				//子類對象向上轉型
		B c = (B) a;			//父類向下轉型
		c.fun1();				//此方法被子類覆寫了,輸出的是覆寫的
		c.fun2();				//新方法
	}
}

在類B中存在三個方法,全部可以調用。

注意:進行向下轉型操作時,

//本程序是多態性的測試
class A							//定義類A
{
	public void fun1()			//定義類A的fun1方法
	{
		System.out.println("這是類A的fun1方法");
	}
	public void fun2()
	{
		this.fun1();
	}
}
class B extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類B覆寫的fun1方法");
	}
	public void fun3()
	{
		System.out.println("這是類B的fun3方法");
	}
}
public class  TestPol
{
	public static void main(String[] args) 
	{
		//B b = new B();			//定義子類的實例化對象
		//A a = b;				//子類對象向上轉型
		A a = new A();			//定義父類的實例化對象
		B c = (B) a;			//父類向下轉型
		c.fun1();				//此方法被子類覆寫了,輸出的是覆寫的
		c.fun2();				//新方法
	}
}
如果不先進行向上操作的話,會有錯誤信息。

Exception in thread "main" java.lang.ClassCastException: A cannot be cast to B

        at TestPol.main(TestPol.java:31)

4.對象多態性的應用

要求設計一個方法,能夠調用A類任意子類的對象。

//本程序是多態性的測試
class A							//定義類A
{
	public void fun1()			//定義類A的fun1方法
	{
		System.out.println("這是類A的fun1方法");
	}
	public void fun2()
	{
		this.fun1();
	}
}
class B extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類B覆寫的fun1方法");
	}
	public void fun3()
	{
		System.out.println("這是類B的fun3方法");
	}
}
class C extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類C覆寫的fun1方法");
	}
	public void fun4()
	{
		System.out.println("這是類C的fun4方法");
	}
}
public class  TestPol
{
	public static void main(String[] args) 
	{
		fun(new B());
		fun(new C());
	}
	public static void fun(B b)
	{
		b.fun1();
	}
	public static void fun(C c)
	{
		c.fun1();
	}
}

如果子類過多,無法完成這一目標,可以使用對象多態行完成。

//本程序是多態性的測試
class A							//定義類A
{
	public void fun1()			//定義類A的fun1方法
	{
		System.out.println("這是類A的fun1方法");
	}
	public void fun2()
	{
		this.fun1();
	}
}
class B extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類B覆寫的fun1方法");
	}
	public void fun3()
	{
		System.out.println("這是類B的fun3方法");
	}
}
class C extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類C覆寫的fun1方法");
	}
	public void fun4()
	{
		System.out.println("這是類C的fun4方法");
	}
}
public class  TestPol
{
	public static void main(String[] args) 
	{
		fun(new B());
		fun(new C());
	}
	public static void fun(A a)
	{
		a.fun1();
	}	
}

2.instanceof 關鍵字

在對象轉型中經常使用

1.概念

java中使用instanceof判斷一個對象到底是哪個類的實。

對象   instanceof   類        ---------------->他返回的是boolean

//本程序是isntanceof的測試
class A							//定義類A
{
	public void fun1()			//定義類A的fun1方法
	{
		System.out.println("這是類A的fun1方法");
	}
	public void fun2()
	{
		this.fun1();
	}
}
class B extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類B覆寫的fun1方法");
	}
	public void fun3()
	{
		System.out.println("這是類B的fun3方法");
	}
}
public class TestInstanceOf 
{
	public static void main(String[] args) 
	{
		B b = new B();				//定義子類的實例化對象
		A a = b;					//向上轉型
		A a2 = new A();
		System.out.println(a instanceof A);
		System.out.println(a instanceof B);
		System.out.println(a2 instanceof A);
		System.out.println(a2 instanceof B);
	}
}

1.作用

如果傳入的是B類的實例,調用fun3,如果是C類調用fun4

//本程序是isntanceof的測試
class A							//定義類A
{
	public void fun1()			//定義類A的fun1方法
	{
		System.out.println("這是類A的fun1方法");
	}
	public void fun2()
	{
		this.fun1();
	}
}
class B extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類B覆寫的fun1方法");
	}
	public void fun3()
	{
		System.out.println("這是類B的fun3方法");
	}
}
class C extends A				//類B繼承類A
{
	public void fun1()			//覆寫fun1方法
	{
		System.out.println("這是類C覆寫的fun1方法");
	}
	public void fun4()
	{
		System.out.println("這是類C的fun4方法");
	}
}
public class TestInstanceOf 
{
	public static void main(String[] args) 
	{
		fun(new B());
		fun(new C());
	}
	public static void fun(A a)
	{
		if (a instanceof B)
		{
			A a1 = a;			//現在a是子類,先進行向上轉換
			B b = (B) a1;		//父類向下轉換
			b.fun3();
		}
		if (a instanceof C)
		{
			A a1 = a;			//現在a是子類,先進行向上轉換
			C c = (C) a1;		//父類向下轉換
			c.fun4();
		}
	}
}

注意:開發中,向下轉型操作要進行驗證,確保不會出問題。

如果要增加新的子類,則要修改fun方法,這樣程序就失去了靈活性。所以程序設計重點放在父類上。只要足夠合理,開發非常方便。

一個類永遠不要去繼承已經實現好了的類,只能繼承抽象類或實現接口。


祝大家健健康康,快快樂樂。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章