• <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

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見(jiàn)諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            Java中的向上轉(zhuǎn)型和向下轉(zhuǎn)型

            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();   //
            這是錯(cuò)誤的,u()方法沒(méi)有在useful類(lèi)型中調(diào)用。

                     Useful[] x =
                     {
                      new Useful(),
                      new MoreUseful(),
                      new MoreUseful2(),
                      new ExtendsMoreUseful2()
                      };
            //
            聲明一個(gè)變量數(shù)組,保存每個(gè)Useful對(duì)象的引用,
                         //
            那么每一個(gè)Useful對(duì)象就會(huì)自動(dòng)向上轉(zhuǎn)型為Useful

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

            x[i].g(); //這是動(dòng)態(tài)綁定,將方法的調(diào)用和方法主體關(guān)聯(lián)起來(lái)就是動(dòng)態(tài)綁定。

            }

            運(yùn)行結(jié)果:

            g() in the Useful class        // 由于x[0].g()這一句中調(diào)用g()方法實(shí)際的對(duì)象類(lèi)型是

                                                        // 基類(lèi)Useful類(lèi)型,故將調(diào)用基類(lèi)中的f()方法。(沒(méi)有轉(zhuǎn)型)
                                         

            g() in the MoreUseful class      // 由于x[1].g()這一句中調(diào)用g()方法實(shí)際的對(duì)象類(lèi)型是

                                                               //子類(lèi)Moreuseful類(lèi)型,故將調(diào)用子類(lèi)Moreuseful

                                                              //   覆蓋父 類(lèi)的g()方法。(向上轉(zhuǎn)型)
                                              

            u() in the MoreUseful2 class        // 由于x[2]MoreUseful2類(lèi)型,故可以對(duì)其向下轉(zhuǎn)型調(diào)

                                                                    // MoreUseful2中的擴(kuò)展方法u()。(向下轉(zhuǎn)型)

            g() in the MoreUseful2 class        // x[2].g()這一句中調(diào)用g()方法實(shí)際的對(duì)象類(lèi)型是子

                                                               // 類(lèi)Moreuseful類(lèi)型,故將調(diào)用子類(lèi)Moreuseful
                                                                   //  
            覆蓋父類(lèi)的g()方法。(向上轉(zhuǎn)型)

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

                                               // 它是MoreUseful2的子類(lèi),存在is-a關(guān)系,故可以對(duì)其向下轉(zhuǎn)

                                      // ,將調(diào)ExtendMoreUseful2中的擴(kuò)展的方法u()。(向下轉(zhuǎn)型)

            g() in the ExtendsMoreUseful2 class     // x[3].g()這一句中調(diào)用g()方法實(shí)際的對(duì)象類(lèi)型

                                                                               //是子類(lèi)ExtendMoreuseful類(lèi)型故將調(diào)用
                                                //
            子類(lèi)ExtendMoreuseful中覆蓋父類(lèi)的g()方法。(向上轉(zhuǎn)型)


            分析和結(jié)論:

            (一)向上轉(zhuǎn)型

            1)定義: 把對(duì)某個(gè)對(duì)象的引用視為對(duì)其基類(lèi)引用的做法被稱(chēng)為向上轉(zhuǎn)型
                
            這主要是由于子類(lèi)的對(duì)象可以看成是基類(lèi)的對(duì)象這原因而得來(lái)的,也就是具有is-a關(guān)系。

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

            2)基類(lèi)可以接收發(fā)給導(dǎo)出類(lèi)的任何消息,因?yàn)槎哂型耆嗤慕涌冢覀冎恍枰?span lang="EN-US">

            從導(dǎo)出類(lèi)向上轉(zhuǎn)型,永遠(yuǎn)不需要知道正在處理的對(duì)象的確切類(lèi)型,這也就是多態(tài)性決

            定的。利用多態(tài)性,具有同樣方法名和方法特征的方法根據(jù)調(diào)用方法的對(duì)象的類(lèi)型,

            可以產(chǎn)生不同的動(dòng)作,這極大地增加了程序員的表達(dá)能力。


                
            回頭再看一看上面這個(gè)例子中的一段for循環(huán)代碼,

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

            x[i].g(); //動(dòng)態(tài)綁定

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

            在這種情況下,編譯器是怎么知道調(diào)用哪個(gè)方法的呢?這是一個(gè)動(dòng)態(tài)綁定的問(wèn)題,見(jiàn)

            下面。

            (二)動(dòng)態(tài)綁定

            1)定義:將方法的調(diào)用和方法主體關(guān)聯(lián)起來(lái)就是動(dòng)態(tài)綁定。

            比如:x[i].g();這就是一個(gè)動(dòng)態(tài)綁定,x[i]是一個(gè)對(duì)象類(lèi)型,g()是一個(gè)不知道是屬于

            哪個(gè)對(duì)象的方法,將這兩個(gè)兩個(gè)聯(lián)合在一起,就是一個(gè)綁定。

            2要注意:Java中除了staticfinal方法(private方法屬于final方法,因?yàn)?span lang="EN-US">fianl方法

            不可以覆蓋,static方法是一個(gè)全局方法,屬于所有類(lèi)共享,不在多態(tài)范圍內(nèi))之外,

            其他所有的方法都是動(dòng)態(tài)綁定,這就意味著在通常情況下,我們不必判定是否應(yīng)該進(jìn)

            行動(dòng)態(tài)綁定,因?yàn)檫@個(gè)會(huì)自動(dòng)發(fā)生。

            3)接著上面的答復(fù)。編譯器是怎么知道調(diào)用哪個(gè)方法的呢?

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

            個(gè)實(shí)際的方法由所引用的對(duì)象的類(lèi)型決定。那么調(diào)用的實(shí)際方法可能是父類(lèi)中沒(méi)有被

            子類(lèi)覆蓋的方法,也可能是子類(lèi)中覆蓋父類(lèi)的方法,主要看調(diào)用這個(gè)方法的實(shí)際的對(duì)

            象類(lèi)型是哪一個(gè)。


            (三)向下轉(zhuǎn)型

            既然有向上轉(zhuǎn)型,那么有沒(méi)有向下轉(zhuǎn)型呢?

            答:有

            1)概述

            繼承可以確保所有的子類(lèi)類(lèi)具有基類(lèi)的接口,且絕對(duì)不會(huì)少。那么子類(lèi)除了有父類(lèi)的

            方法,也可以有自己的額外的新方法(這些方法是基類(lèi)所沒(méi)有的),那么一旦向上轉(zhuǎn)

            型,就不能調(diào)用子類(lèi)中的新方法,那么能不能用一種方式調(diào)用這些新方法呢?當(dāng)然有

            了,這時(shí)候就需要向下轉(zhuǎn)型。

            2)向下轉(zhuǎn)型

            將超類(lèi)的引用強(qiáng)制轉(zhuǎn)換為子類(lèi)類(lèi)型就叫做向下轉(zhuǎn)型。

            注意:將超類(lèi)的引用賦給為子類(lèi)類(lèi)型的變量(沒(méi)有進(jìn)行顯示地強(qiáng)制轉(zhuǎn)換)是一個(gè)編譯

            錯(cuò)誤。

            例子:

            還是上面的for循環(huán)代碼

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

            x[i].g();

            }


            分析:x[i]可以代表具體的Useful對(duì)象類(lèi)型,當(dāng)它是MoreUseful2ExtendsMoreUseful2

            對(duì)象類(lèi)型時(shí),就可以調(diào)用該對(duì)象的額外方法u(),v(),w()也就是當(dāng)對(duì)象x[i]Moreusful對(duì)

            象存在is-a關(guān)系時(shí),才可以進(jìn)行向下轉(zhuǎn)型,如果要轉(zhuǎn)換的對(duì)象類(lèi)型與指定的對(duì)象類(lèi)型不

            存在is-a關(guān)系時(shí),會(huì)產(chǎn)生一個(gè)ClassCastException異常。

            總之:

            向下轉(zhuǎn)型時(shí),對(duì)象只能強(qiáng)制轉(zhuǎn)換為其本身類(lèi)型或者其超類(lèi)類(lèi)型。比如,

            當(dāng)x[i]ExtendsMoreUseful2對(duì)象時(shí),可以把他轉(zhuǎn)換為其本身ExtendsMoreUseful2對(duì)象類(lèi)

            型,也可以把它轉(zhuǎn)換為其基類(lèi)MoreUseful2類(lèi)型。但是在編譯時(shí)候還不知道這個(gè)x[i]是代

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

            到的類(lèi)型)x[i] " 進(jìn)行轉(zhuǎn)換。x[i]在這里是就我這個(gè)例子來(lái)說(shuō)明的,你也可以使用其它的

            英文代替,其意義是一切符合規(guī)定的需要被轉(zhuǎn)換的對(duì)象。

            下面還有個(gè)關(guān)于向上轉(zhuǎn)型和向下轉(zhuǎn)型的例子,

            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();//
            向下轉(zhuǎn)型,可以調(diào)用導(dǎo)出類(lèi)中的擴(kuò)展方法
            }

            public static void playDemo2(ClassAbstract2 ObjectParameter)
            {
               ObjectParameter.play2();//
            向上轉(zhuǎn)型,可以調(diào)用導(dǎo)出類(lèi)中的覆蓋方法
            }

            /**
            * @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);

            }

            }


            運(yùn)行結(jié)果:
            play1() is in the ClassDerived1
            play2() is in the ClassDerived2

             

             

            posted on 2009-07-27 13:00 肥仔 閱讀(1097) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Web-后臺(tái)

            久久综合欧美成人| 欧美粉嫩小泬久久久久久久| 久久午夜伦鲁片免费无码| 久久AV无码精品人妻糸列| 亚洲国产精品久久久天堂| 91精品国产91久久久久久青草| 久久99精品国产麻豆不卡| 国产亚洲美女精品久久久2020| 久久综合给久久狠狠97色| 久久久91人妻无码精品蜜桃HD| 国内精品伊人久久久久妇| 国产韩国精品一区二区三区久久| 久久成人国产精品一区二区| 国产成人精品久久| 久久精品视频91| 久久99精品国产| 97久久国产露脸精品国产| 久久黄视频| 久久综合中文字幕| 国内精品久久久久久久97牛牛| 久久久久香蕉视频| 国产亚洲成人久久| 亚洲狠狠综合久久| 国产精品久久久久久影院 | 亚洲婷婷国产精品电影人久久| 无码AV中文字幕久久专区| 久久精品亚洲福利| 久久这里只有精品久久| 久久精品国产清高在天天线| 亚洲美日韩Av中文字幕无码久久久妻妇 | 久久se精品一区精品二区| 伊色综合久久之综合久久| 一本久久久久久久| 久久青青草原国产精品免费 | 久久天天婷婷五月俺也去| 国产999精品久久久久久| 2021久久精品国产99国产精品| 天天爽天天狠久久久综合麻豆| 伊人久久无码精品中文字幕| 亚洲色欲久久久久综合网| 久久人做人爽一区二区三区|