• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數據加載中……

            Java中的向上轉型和向下轉型

            class Useful

            {
            int value = 20;
            public void f() {System.out.println("f() in the Useful class");}
            public void g() {System.out.println("g() in the Useful class");}
            }

            class MoreUseful extends Useful {
            int value = 21;
            public void f() {System.out.println("f() in the MoreUseful class");}
            public void g() {System.out.println("g() in the MoreUseful class");}
            public void u() {System.out.println("u() in the MoreUseful class");}
            public void v() {}
            public void w() {}
            }

            class MoreUseful2 extends Useful {
            int value = 21;
            public void f() {System.out.println("f() in the MoreUseful2 class");}
            public void g() {System.out.println("g() in the MoreUseful2 class");}
            public void u() {System.out.println("u() in the MoreUseful2 class");}
            public void v() {}
            public void w() {}
            }


            class ExtendsMoreUseful2 extends MoreUseful2 {
            int value = 22;
            public void f() {System.out.println("f() in the ExtendsMoreUseful2 class");}
            public void g() {System.out.println("g() in the ExtendsMoreUseful2 class");}
            public void u() {System.out.println("u() in the ExtendsMoreUseful2 class");}
            public void v() {}
            public void w() {}
            }

            public class RTTI {
            public static void main(String[] args) {

            //Useful useful = new MoreUseful();
            //useful.u();   //
            這是錯誤的,u()方法沒有在useful類型中調用。

                     Useful[] x =
                     {
                      new Useful(),
                      new MoreUseful(),
                      new MoreUseful2(),
                      new ExtendsMoreUseful2()
                      };
            //
            聲明一個變量數組,保存每個Useful對象的引用,
                         //
            那么每一個Useful對象就會自動向上轉型為Useful

            for(int i=0;i<x.length;i++)
            {
            if(x[i] instanceof MoreUseful2) //
            判斷instanceof左邊的對象是否是右邊的類的實例。
            {
               MoreUseful2 moreuseful2 = (MoreUseful2)x[i];//
            向下轉型(具體解釋見下面的分析)
               moreuseful2.u();
            }

            x[i].g(); //這是動態綁定,將方法的調用和方法主體關聯起來就是動態綁定。

            }

            運行結果:

            g() in the Useful class        // 由于x[0].g()這一句中調用g()方法實際的對象類型是

                                                        // 基類Useful類型,故將調用基類中的f()方法。(沒有轉型)
                                         

            g() in the MoreUseful class      // 由于x[1].g()這一句中調用g()方法實際的對象類型是

                                                               //子類Moreuseful類型,故將調用子類Moreuseful

                                                              //   覆蓋父 類的g()方法。(向上轉型)
                                              

            u() in the MoreUseful2 class        // 由于x[2]MoreUseful2類型,故可以對其向下轉型調

                                                                    // MoreUseful2中的擴展方法u()。(向下轉型)

            g() in the MoreUseful2 class        // x[2].g()這一句中調用g()方法實際的對象類型是子

                                                               // Moreuseful類型,故將調用子類Moreuseful
                                                                   //  
            覆蓋父類的g()方法。(向上轉型)

            u() in the ExtendsMoreUseful2 class     // 由于x[3]ExtendMoreUseful2類型,

                                               // 它是MoreUseful2的子類,存在is-a關系,故可以對其向下轉

                                      // ,將調ExtendMoreUseful2中的擴展的方法u()。(向下轉型)

            g() in the ExtendsMoreUseful2 class     // x[3].g()這一句中調用g()方法實際的對象類型

                                                                               //是子類ExtendMoreuseful類型故將調用
                                                //
            子類ExtendMoreuseful中覆蓋父類的g()方法。(向上轉型)


            分析和結論:

            (一)向上轉型

            1)定義: 把對某個對象的引用視為對其基類引用的做法被稱為向上轉型
                
            這主要是由于子類的對象可以看成是基類的對象這原因而得來的,也就是具有is-a關系。

            比如:
                 Useful useful = new MoreUseful();//
            右邊是一個子類的對象,而左邊是一個父類類型
                                                  //
            的變量,指向右邊的子類對象。

            2)基類可以接收發給導出類的任何消息,因為二者有完全相同的接口,我們只需要

            從導出類向上轉型,永遠不需要知道正在處理的對象的確切類型,這也就是多態性決

            定的。利用多態性,具有同樣方法名和方法特征的方法根據調用方法的對象的類型,

            可以產生不同的動作,這極大地增加了程序員的表達能力。


                
            回頭再看一看上面這個例子中的一段for循環代碼,

            for(int i=0;i<x.length;i++)
            {
            if(x[i] instanceof MoreUseful2)   //
            判斷instanceof左邊的對象是否是右邊的類的實例。
            {
            MoreUseful2 moreuseful2 = (MoreUseful2)x[i]; //
            向下轉型(具體解釋見下面的分析)
            moreuseful2.u();
            }

            x[i].g(); //動態綁定

            }
                
            主要看x[i].g();這一句話,現在我們還不知道x[i]這個到底是指代哪一個Useful對象,

            在這種情況下,編譯器是怎么知道調用哪個方法的呢?這是一個動態綁定的問題,見

            下面。

            (二)動態綁定

            1)定義:將方法的調用和方法主體關聯起來就是動態綁定。

            比如:x[i].g();這就是一個動態綁定,x[i]是一個對象類型,g()是一個不知道是屬于

            哪個對象的方法,將這兩個兩個聯合在一起,就是一個綁定。

            2要注意:Java中除了staticfinal方法(private方法屬于final方法,因為fianl方法

            不可以覆蓋,static方法是一個全局方法,屬于所有類共享,不在多態范圍內)之外,

            其他所有的方法都是動態綁定,這就意味著在通常情況下,我們不必判定是否應該進

            行動態綁定,因為這個會自動發生。

            3)接著上面的答復。編譯器是怎么知道調用哪個方法的呢?

            主要還是x[i].g();這一句話的作用,x[i]在調用方法的時候,會調用實際的方法,這

            個實際的方法由所引用的對象的類型決定。那么調用的實際方法可能是父類中沒有被

            子類覆蓋的方法,也可能是子類中覆蓋父類的方法,主要看調用這個方法的實際的對

            象類型是哪一個。


            (三)向下轉型

            既然有向上轉型,那么有沒有向下轉型呢?

            答:有

            1)概述

            繼承可以確保所有的子類類具有基類的接口,且絕對不會少。那么子類除了有父類的

            方法,也可以有自己的額外的新方法(這些方法是基類所沒有的),那么一旦向上轉

            型,就不能調用子類中的新方法,那么能不能用一種方式調用這些新方法呢?當然有

            了,這時候就需要向下轉型。

            2)向下轉型

            將超類的引用強制轉換為子類類型就叫做向下轉型。

            注意:將超類的引用賦給為子類類型的變量(沒有進行顯示地強制轉換)是一個編譯

            錯誤。

            例子:

            還是上面的for循環代碼

            for(int i=0;i<x.length;i++)
            {
            if(x[i] instanceof MoreUseful2) //    
            判斷instanceof左邊的對象是否是右邊的類的實例。
            {
            MoreUseful2 moreuseful2 = (MoreUseful2)x[i]; //
            向下轉型
            moreuseful2.u();
            }

            x[i].g();

            }


            分析:x[i]可以代表具體的Useful對象類型,當它是MoreUseful2ExtendsMoreUseful2

            對象類型時,就可以調用該對象的額外方法u(),v(),w()也就是當對象x[i]Moreusful

            象存在is-a關系時,才可以進行向下轉型,如果要轉換的對象類型與指定的對象類型不

            存在is-a關系時,會產生一個ClassCastException異常。

            總之:

            向下轉型時,對象只能強制轉換為其本身類型或者其超類類型。比如,

            x[i]ExtendsMoreUseful2對象時,可以把他轉換為其本身ExtendsMoreUseful2對象類

            型,也可以把它轉換為其基類MoreUseful2類型。但是在編譯時候還不知道這個x[i]是代

            表那個具體對象類型只知道這個x[i]是基類類型引用,所以要用這樣的形式" (想要要得

            到的類型)x[i] " 進行轉換。x[i]在這里是就我這個例子來說明的,你也可以使用其它的

            英文代替,其意義是一切符合規定的需要被轉換的對象。

            下面還有個關于向上轉型和向下轉型的例子,

            abstract class ClassAbstract1{}
            class ClassDerived1 extends ClassAbstract1
            {
            public void play1()
            {
               System.out.println("play1() is in the ClassDerived1");
            }
            }
            abstract class ClassAbstract2{public abstract void play2();}
            class ClassDerived2 extends ClassAbstract2
            {
            public void play2()
            {
               System.out.println("play2() is in the ClassDerived2");
            }
            }


            public class E14_UnCast {

            public static void playDemo1(ClassAbstract1 ObjectParameter)
            {
               ((ClassDerived1)ObjectParameter).play1();//
            向下轉型,可以調用導出類中的擴展方法
            }

            public static void playDemo2(ClassAbstract2 ObjectParameter)
            {
               ObjectParameter.play2();//
            向上轉型,可以調用導出類中的覆蓋方法
            }

            /**
            * @param args
            */
            public static void main(String[] args) {
               // TODO Auto-generated method stub
               ClassAbstract1 classabstract = new ClassDerived1();
               playDemo1(classabstract);
               ClassAbstract2 classabstract2 = new ClassDerived2();
               playDemo2(classabstract2);

            }

            }


            運行結果:
            play1() is in the ClassDerived1
            play2() is in the ClassDerived2

             

             

            posted on 2009-07-27 13:00 肥仔 閱讀(1086) 評論(0)  編輯 收藏 引用 所屬分類: Web-后臺

            中文精品99久久国产| 久久亚洲精品视频| 中文字幕亚洲综合久久| 久久精品国产亚洲av高清漫画| 国产激情久久久久影院小草| 国产精品福利一区二区久久| 97久久天天综合色天天综合色hd | 久久久久se色偷偷亚洲精品av| 国产精品成人久久久久久久| 久久r热这里有精品视频| 精品无码久久久久久尤物| 久久久亚洲欧洲日产国码aⅴ| 色狠狠久久AV五月综合| 国产成人无码久久久精品一| .精品久久久麻豆国产精品| 26uuu久久五月天| 色8激情欧美成人久久综合电| 一日本道伊人久久综合影| 久久精品国产亚洲αv忘忧草| 亚洲AV乱码久久精品蜜桃| 国产91久久精品一区二区| 青青草原综合久久大伊人精品| 久久播电影网| 久久久久亚洲AV无码专区首JN| 久久人人爽人人爽人人AV东京热 | 色诱久久久久综合网ywww| 亚洲AV无码久久精品蜜桃| 国产一区二区三区久久精品| 99久久精品免费看国产免费| 日韩一区二区三区视频久久| 亚洲国产另类久久久精品黑人| av无码久久久久久不卡网站 | 久久久久国产亚洲AV麻豆| 久久久久久综合网天天| 久久免费精品一区二区| 久久综合九色综合欧美就去吻| 亚洲中文久久精品无码ww16| 99久久人人爽亚洲精品美女| 无码AV中文字幕久久专区 | 久久精品国产一区二区| 香蕉久久av一区二区三区 |