Java 三大特質之多態

我覺得一個高水平的老師可以知識講解的簡單明瞭,而一個低水平的老師則會把知識更加複雜化,講解的晦澀難懂。原因在於其沒有深刻的理解,抓住事物的本質特徵。其講解的複雜度也就負相關於了學生的理解接收程度。因此本博客寫作力求深刻理解事物本質,然後用簡潔明瞭的語言將其闡述清楚。

多態一個引用變量的多種狀態。具體一點就是,程序定義的父類引用變量所指向的子類對象在編程時是不確定的,而是在程序運行期間確定的。怎麼理解?看下面代碼,現在講太多道理太空洞。

public class Test12 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Animal1 a= new Cat1();
		a.speak();
		a =new Dog1();
		a.speak();
	}
}
class Animal1{
	String name;
	int age;
	
	public void speak(){
		System.out.println("我是動物,不知道怎麼叫!!");		
	}
}
class Cat1 extends Animal1{
	//Overriding
	public void speak(){
		System.out.println("我是小貓,喵喵喵!");
	}
}
class Dog1 extends Animal1{
	//Overriding
	public void speak(){
		System.out.println("我是小狗,汪汪汪!");
	}
}


可以看到,同一個引用變量 a  ,在不同的時刻既可以指向new Cat(),又可以指向new Dog()。這就是“多態”。

慢着,以前我們在創建一個類的對象時,是這樣的Cat cat=new Cat(),但是卻是這樣Animal a=new Cat();。這樣做可以嗎?

答案是肯定的。由於Cat可以自動“向上轉型”爲Animal,所以 a 是可以指向Cat 的實例對象的。向上轉型”的概念是初次接觸,本來應該加以介紹,限於篇幅所限,暫且按住不表。留待下文分解。

繼續說“多態”,看下面Code

public class Test12 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Animal1 a= new Cat1();
		a.speak();
		a.eat();
		
		a =new Dog1();
		a.speak();
	}
}
class Animal1{
	String name;
	int age;
	
	public void speak(){
		System.out.println("我是動物,不知道怎麼叫!!");		
	}
}
class Cat1 extends Animal1{
	//Overriding
	public void speak(){
		System.out.println("我是小貓,喵喵喵!");
	}
	public void eat(){
		System.out.println("我是小貓,我愛喫魚!");
	}
}
class Dog1 extends Animal1{
	//Overriding
	public void speak(){
		System.out.println("我是小狗,汪汪汪!");
	}
}

在上一個code的基礎上,爲Cat增加的eat()方法,並且用父類引用a來調用。可以嗎?我們發現編譯都編不過去。在a.eat() 處報錯。eclipse 提示“The method eat() is undefined for the type Animal1”

看看,提示的很清楚!說明什麼,說明現在父類引用a 的類型是animal ,不是Cat,因此它能夠調用的只能是animal中存在的方法,如果animal中不存在,則無法調用。

再看code

public class Test12 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Animal1 a= new Cat1();
		a.speak();
		a.eat();
		
		a =new Dog1();
		a.speak();
	}
}
class Animal1{
	String name;
	int age;
	
	public void speak(){
		System.out.println("我是動物,不知道怎麼叫!!");		
	}
	public void eat(){
		System.out.println("我是動物,我就要喫!");
	}
}
class Cat1 extends Animal1{
	//Overriding
	public void speak(){
		System.out.println("我是小貓,喵喵喵!");
	}
}
class Dog1 extends Animal1{
	//Overriding
	public void speak(){
		System.out.println("我是小狗,汪汪汪!");
	}
}

在上面的code中,在animal中寫了eat()方法,然後在父類引用a 處調用eat()方法,完全正確。

總結一下,在實現多態以後,父類引用的類型是父類的類型,而不是子類的類型;父類引用可以調用的方法是被子類繼承或者重寫的方法。




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