日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
講解一下Java中的多態(tài)

多態(tài)(Polymorphism)屬于面向?qū)ο笕筇卣髦?,它的前提是封裝形成獨立體,獨立體之間存在繼承關系,從而產(chǎn)生多態(tài)機制。多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。

創(chuàng)新互聯(lián)主要從事網(wǎng)站建設、做網(wǎng)站、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務谷城,10余年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:13518219792

重載式多態(tài),也叫編譯時多態(tài)。也就是說這種多態(tài)再編譯時已經(jīng)確定好了。重載大家都知道,方法名相同而參數(shù)列表不同的一組方法就是重載。在調(diào)用這種重載的方法時,通過傳入不同的參數(shù)最后得到不同的結果。

但是這里是有歧義的,有的人覺得不應該把重載也算作多態(tài)。因為很多人對多態(tài)的理解是:程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時并不確定,而是在程序運行期間才確定,這種情況叫做多態(tài)。 這個定義中描述的就是我們的第二種多態(tài)—重寫式多態(tài)。并且,重載式多態(tài)并不是面向?qū)ο缶幊烫赜械模鄳B(tài)卻是面向?qū)ο笕筇匦灾唬ㄈ绻艺f的不對,記得告訴我。。)。

我覺得大家也沒有必要在定義上去深究這些,我的理解是:同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力就是多態(tài),所以我認為重載也是一種多態(tài),如果你不同意這種觀點,我也接受。

重寫式多態(tài),也叫運行時多態(tài)。這種多態(tài)通過動態(tài)綁定(dynamic binding)技術來實現(xiàn),是指在執(zhí)行期間判斷所引用對象的實際類型,根據(jù)其實際的類型調(diào)用其相應的方法。也就是說,只有程序運行起來,你才知道調(diào)用的是哪個子類的方法。 這種多態(tài)通過函數(shù)的重寫以及向上轉型來實現(xiàn),我們上面代碼中的例子就是一個完整的重寫式多態(tài)。我們接下來講的所有多態(tài)都是重寫式多態(tài),因為它才是面向?qū)ο缶幊讨姓嬲亩鄳B(tài)。

向上轉型

子類引用的對象轉換為父類類型稱為向上轉型。通俗地說就是是將子類對象轉為父類對象。此處父類對象可以是接口。

看一個大家都知道的例子:

實例

public class Animal {
   public void eat(){
       System.out.println("animal eatting...");
   }
}

public class Cat extends Animal{

   public void eat(){

       System.out.println("我吃魚");
   }
}

public class Dog extends Animal{

   public void eat(){

       System.out.println("我吃骨頭");
   }

   public void run(){
       System.out.println("我會跑");
   }
}

public class Main {

   public static void main(String[] args) {

       Animal animal = new Cat(); //向上轉型
       animal.eat();

       animal = new Dog();
       animal.eat();
   }

}

//結果:
//我吃魚
//我吃骨頭

這就是向上轉型,Animal animal = new Cat(); 將子類對象 Cat 轉化為父類對象 Animal。這個時候 animal 這個引用調(diào)用的方法是子類方法。

轉型過程中需要注意的問題

  1. 向上轉型時,子類單獨定義的方法會丟失。比如上面Dog類中定義的run方法,當animal引用指向Dog類實例時是訪問不到run方法的,animal.run()會報錯。
  2. 子類引用不能指向父類對象。Cat c = (Cat)new Animal()這樣是不行的。

向上轉型的好處

  1. 減少重復代碼,使代碼變得簡潔。
  2. 提高系統(tǒng)擴展性。

向下轉型

與向上轉型相對應的就是向下轉型了。向下轉型是把父類對象轉為子類對象。(請注意!這里是有坑的。)

案例驅(qū)動

先看一個例子:

//還是上面的animal和cat dog
Animal a = new Cat();
Cat c = ((Cat) a);
c.eat();
//輸出  我吃魚
Dog d = ((Dog) a);
d.eat();
// 報錯 : java.lang.ClassCastException:com.chengfan.animal.Cat cannot be cast to com.chengfan.animal.Dog
Animal a1 = new Animal();
Cat c1 = ((Cat) a1);
c1.eat();
// 報錯 : java.lang.ClassCastException:com.chengfan.animal.Animal cannot be cast to com.chengfan.animal.Cat

為什么第一段代碼不報錯呢?相比你也知道了,因為 a 本身就是 Cat 對象,所以它理所當然的可以向下轉型為 Cat,也理所當然的不能轉為 Dog,你見過一條狗突然就變成一只貓這種操蛋現(xiàn)象?

而 a1 為 Animal 對象,它也不能被向下轉型為任何子類對象。比如你去考古,發(fā)現(xiàn)了一個新生物,知道它是一種動物,但是你不能直接說,啊,它是貓,或者說它是狗。

向下轉型注意事項

  1. 向下轉型的前提是父類對象指向的是子類對象(也就是說,在向下轉型之前,它得先向上轉型)
  2. 向下轉型只能轉型為本類對象(貓是不能變成狗的)。

看一個經(jīng)典案例:

實例

class A {
   public String show(D obj) {
       return ("A and D");
   }

   public String show(A obj) {
       return ("A and A");
   }

}

class B extends A{
   public String show(B obj){
       return ("B and B");
   }

   public String show(A obj){
       return ("B and A");
   }
}

class C extends B{

}

class D extends B{

}

public class Demo {
   public static void main(String[] args) {
       A a1 = new A();
       A a2 = new B();
       B b = new B();
       C c = new C();
       D d = new D();

       System.out.println("1--" + a1.show(b));
       System.out.println("2--" + a1.show(c));
       System.out.println("3--" + a1.show(d));
       System.out.println("4--" + a2.show(b));
       System.out.println("5--" + a2.show(c));
       System.out.println("6--" + a2.show(d));
       System.out.println("7--" + b.show(b));
       System.out.println("8--" + b.show(c));
       System.out.println("9--" + b.show(d));
   }
}
//結果:
//1--A and A
//2--A and A
//3--A and D
//4--B and A
//5--B and A
//6--A and D
//7--B and B
//8--B and B
//9--A and D

//能看懂這個結果么?先自分析一下。

前三個,強行分析,還能看得懂。但是第四個,大概你就傻了吧。為什么不是b and b呢?

這里就要學點新東西了。

當父類對象引用變量引用子類對象時,被引用對象的類型決定了調(diào)用誰的成員方法,引用變量類型決定可調(diào)用的方法。如果子類中沒有覆蓋該方法,那么會去父類中尋找。

可能讀起來比較拗口,我們先來看一個簡單的例子:

實例

class X {
   public void show(Y y){
       System.out.println("x and y");
   }

   public void show(){
       System.out.println("only x");
   }
}

class Y extends X {
   public void show(Y y){
       System.out.println("y and y");
   }
   public void show(int i){

   }
}

class main{
   public static void main(String[] args) {
       X x = new Y();
       x.show(new Y());
       x.show();
   }
}
//結果
//y and y
//only x

Y 繼承了 X,覆蓋了 X 中的 show(Y y) 方法,但是沒有覆蓋 show() 方法。

這個時候,引用類型為X的 x 指向的對象為 Y,這個時候,調(diào)用的方法由 Y 決定,會先從 Y 中尋找。執(zhí)行 x.show(new Y());,該方法在 Y 中定義了,所以執(zhí)行的是 Y 里面的方法;

但是執(zhí)行 x.show(); 的時候,有的人會說,Y 中沒有這個方法???它好像是去父類中找該方法了,因為調(diào)用了 X 中的方法。

事實上,Y 類中是有 show() 方法的,這個方法繼承自 X,只不過沒有覆蓋該方法,所以沒有在 Y 中明確寫出來而已,看起來像是調(diào)用了 X 中的方法,實際上調(diào)用的還是 Y 中的。

這個時候再看上面那句難理解的話就不難理解了吧。X是引用變量類型,它決定哪些方法可以調(diào)用;show()和 show(Y y) 可以調(diào)用,而 show(int i)不可以調(diào)用。Y 是被引用對象的類型,它決定了調(diào)用誰的方法:調(diào)用 y 的方法。

上面的是一個簡單的知識,它還不足以讓我們理解那個復雜的例子。我們再來看這樣一個知識:

繼承鏈中對象方法的調(diào)用的優(yōu)先級:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

如果你能理解這個調(diào)用關系,那么多態(tài)你就掌握了。我們回到那個復雜的例子:

abcd 的關系是這樣的:C/D —> B —> A

我們先來分析4 : a2.show(b)

首先,a2是類型為A的引用類型,它指向類型為B的對象。A確定可調(diào)用的方法:show(D obj)和show(A obj)。

a2.show(b) ==> this.show(b),這里this指的是B。然后.在B類中找show(B obj),找到了,可惜沒用,因為show(B obj)方法不在可調(diào)用范圍內(nèi),this.show(O)失敗,進入下一級別:super.show(O),super指的是A。在A 中尋找show(B obj),失敗,因為沒用定義這個方法。進入第三級別:this.show((super)O),this指的是B。在B中找show((A)O),找到了:show(A obj),選擇調(diào)用該方法。

輸出:B and A

如果你能看懂這個過程,并且能分析出其他的情況,那你就真的掌握了。

我們再來看一下9:b.show(d)

首先,b為類型為B的引用對象,指向類型為B的對象。沒有涉及向上轉型,只會調(diào)用本類中的方法。

在B中尋找show(D obj),方法?,F(xiàn)在你不會說沒找到了吧?找到了,直接調(diào)用該方法。

輸出 A and D。

總結

本篇文章的內(nèi)容大體上就是這些了。我們來總結一下。

  1. 多態(tài),簡而言之就是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。
  2. 多態(tài)的分類:運行時多態(tài)和編譯時多態(tài)。
  3. 運行時多態(tài)的前提:繼承(實現(xiàn)),重寫,向上轉型
  4. 向上轉型與向下轉型。
  5. 繼承鏈中對象方法的調(diào)用的優(yōu)先級:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

本文標題:講解一下Java中的多態(tài)
文章起源:http://www.5511xx.com/article/ccesieh.html