<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    zxbyhcsdn

     

    關(guān)于this和super有必要理解清楚的地方

    關(guān)于this和super又必要理解清楚的地方!重要的,多態(tài)的關(guān)鍵

    二話不說(shuō),先來(lái)一段代碼,比較短,需要付出一點(diǎn)點(diǎn)耐心(估計(jì)一上來(lái)就是代碼,又會(huì)趕走很多人吧.....)

    //父類
    class FatherClass {
        public int value;
        public void f() {
            this.run();//注意這兒的是this,注意
        }
        public void run(){
            System.out.println("FatherClass.run():"+this.value);
        }
    }

    //子類
    class ChildClass extends FatherClass {
        public int value = 100;
        public void ff() {
            super.run();//注意這兒的是super,注意
        }
        //重寫
        public void run(){
            System.out.println("ChildClass.run():"+super.value);
        }
    }

    //孫子類,這兒用了一個(gè)拼音,偷懶一下,記不到那個(gè)孫子的單詞了。寒啊...當(dāng)初還過四級(jí),現(xiàn)在忘光光
    class SunziClass extends ChildClass {
        public int value = 200;
        //再次重寫
        public void run() {
            System.out.println("SunziClass.run():"+super.value);
        }
    }

    //這兒是調(diào)用的Main
    public class TestInherit {
          public static void main(String[] args) {
                    FatherClass fc = new ChildClass();
                    fc.f();
                    FatherClass fc1 = new SunziClass();
                    fc1.f();
                    ChildClass cc = new SunziClass();
                    cc.ff();
         }
    }

    想一想運(yùn)行結(jié)果,注意那個(gè)this和super。有點(diǎn)暈頭把,不要暈,穩(wěn)住!自己想一下結(jié)果,然后再來(lái)看運(yùn)行結(jié)果。

    運(yùn)行結(jié)果如下:
    ChildClass.run():0;
    SunziClass.run():100;
    FatherClass.run():0;

    估計(jì)有不少人會(huì)大吃一驚!其他不吃驚的人可以散了!吃驚的人繼續(xù)看下面的。

    this代表什么?這兒代表New出來(lái)的那個(gè)玩意兒在堆空間的引用地址
    對(duì)于下面的這一句:
    FatherClass fc1 = new SunziClass();
    fc1這個(gè)變量里面放的就是this,是new SunziClass()這個(gè)玩意兒在堆空間的引用地址.
    只是這兒fc1是定義成FatherClass,只有FatherClass的屬性和方法是可見的,不過這不是本文討論的重點(diǎn).

    所以說(shuō)在父類里面寫的this其實(shí)就是這個(gè)父類或者他的子類,孫子類,曾孫子類... 在運(yùn)行的時(shí)候[重復(fù)一次哈,運(yùn)行的時(shí)候runtime], New 子類()或者New 孫子類()或者New 曾子類()或者....的堆空間的引用地址.
    [再重復(fù)一次,FatherClass里面的this,子類里面的this...都是一樣的,指向New出來(lái)的那玩意兒的引用地址]

    很神奇哈!!嘿嘿,這個(gè)其實(shí)就是 多態(tài)的體現(xiàn),也是多態(tài)的實(shí)現(xiàn)基礎(chǔ).看父類或者接口定義了方法調(diào)用的邏輯,子類可以根據(jù)需要改變算法! 這樣就可以將關(guān)注的方面分為兩個(gè)層面,一:關(guān)注方法調(diào)用的業(yè)務(wù)邏輯[做什么],二:關(guān)注方法的實(shí)現(xiàn)[怎么做].  "做什么和怎么做",這玩意兒好像在軟件工程里面比較眼熟哦!!!!

    問題分解了,而且可復(fù)用性也大大提高了.

    好了,this總結(jié)完了,好像越說(shuō)越暈了... 再穩(wěn)一下,看看Super

    下面再來(lái)說(shuō)super
    說(shuō)之前,分析一下內(nèi)存多,這個(gè)圖,挖卡,蜘蛛網(wǎng)來(lái)也....




    現(xiàn)在看這兩句:
    ChildClass cc = new SunziClass();
    cc.ff();
    這兒SunziClass里面沒有重寫父類ChildClass的ff方法,
    所以是執(zhí)行的父類ChildClass的ff方法.這個(gè)方法里面有一個(gè)super.Run();
    這兒實(shí)際上就執(zhí)行到了FatherClass的Run()方法.

    這說(shuō)明什么啦.
    說(shuō)明super只是記錄對(duì)象內(nèi)部的父類的特征(屬性和方法)的一個(gè)引用
    (注意哈:這兒super不是指向父類對(duì)象的引用地址哈,new出來(lái)的玩意兒才在堆里面分配空間有引用地址,這兒沒有去new一個(gè)父類對(duì)象哈,只是執(zhí)行了父類的構(gòu)造函數(shù)將父類的特征生成了,但是屬于New出來(lái)的那個(gè)子類對(duì)象)
    估計(jì)上面這段話也夠暈人了...

    實(shí)踐一下,你可以寫
    public FatherClass getThis()
    {
        return this;
    }
    編譯通過,沒有任何問題
    但是你寫
    public FatherClass getSuper()
    {
        return super;
    }

    嘿嘿,編譯出錯(cuò)! 為什么啦,
    因?yàn)閟uper并不是一個(gè)堆空間里面的一個(gè)對(duì)象的引用地址,而this才是堆空間里面的一個(gè)對(duì)象的引用地址
        super只能在對(duì)象內(nèi)部使用,而this可以在對(duì)象內(nèi)部使用也可以返回出對(duì)象外.
        super是死的,編譯的時(shí)候就定死了super的指向了,而this是活的,在運(yùn)行時(shí)候決定其指向.

    再說(shuō)一下,子類實(shí)例化對(duì)象,并沒有去實(shí)例化他的父類對(duì)象,也就是說(shuō),那個(gè)子類對(duì)象里面并沒有一個(gè)父類對(duì)象,
    那你說(shuō)沒有父類對(duì)象,為什么子類構(gòu)造函數(shù)要執(zhí)行父類的構(gòu)造函數(shù)啦,那是因?yàn)樾枰獎(jiǎng)?chuàng)建父類的特征賦予子類,但是是由子類所有,而super就是用來(lái)區(qū)別是是否是父類對(duì)象的特征的.
    重寫父類方法屬性,就是再創(chuàng)建了一個(gè)子類的特征,當(dāng)你用this的時(shí)候,就覆蓋了父類的特征了,但是父類特征還在那兒,用super就能訪問道,但是只能在對(duì)象的內(nèi)部使用.對(duì)象外面就只能看到覆蓋了父類特征的子類特征了.

    寫完收工,我Cao,寫了2個(gè)小時(shí).....
    其實(shí)寫了這么一大堆,就是一句:"this是當(dāng)前對(duì)象在堆空間的引用地址,super是當(dāng)前對(duì)象的父類特征的引用"

    有什么不同的見解歡迎討論...共同進(jìn)步!!!

    posted on 2008-07-21 15:35 zxbyh 閱讀(1633) 評(píng)論(11)  編輯  收藏 所屬分類: J2se

    評(píng)論

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-21 16:34 隔葉黃鶯

    前面代碼跨度太大,看了有些累,用
    public void f(){
    this.run();//注意這兒的是this,注意
    }

    能緊縮一下,看提眼不會(huì)這么渾。
    Java中的實(shí)例方法都是虛的,調(diào)用實(shí)例方法總隱藏 this 引用。
    其實(shí)就是要死咬住一點(diǎn),不管調(diào)用在方法棧怎么來(lái)轉(zhuǎn)來(lái)轉(zhuǎn)去,this 代表著誰(shuí)不能丟了就好理解了。  回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-21 16:42 zxbyh

    好了,緊縮了,呵呵
      回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-21 23:34 fwy

    ChildClass cc = new SunziClass();
    cc.ff();
    ----------
    最后執(zhí)行到Father類里面的
    public void run(){
    System.out.println("FatherClass.run():"+this.value);
    }
    這里面的this是引用的Sunzi對(duì)象,為什么this.value卻是Father的默認(rèn)value值0呢?  回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-22 10:59 隔葉黃鶯

    這樣解釋吧,深入到虛擬機(jī)這一層,方法的調(diào)用常用以下兩個(gè)指令:

    invokevirtual
    invokespecial

    顧名思義,看到 virtual,應(yīng)該能想到虛方法的調(diào)用,也就是動(dòng)態(tài)綁定,以當(dāng)前實(shí)例的真實(shí)類型來(lái)決定調(diào)用哪個(gè)實(shí)例的方法。

    而 invokespecial,卻比較古板,它是由實(shí)例的引用類型來(lái)決定調(diào)用哪個(gè)方法。

    Java 中的實(shí)例初始化方法<init>,基本可以等同于 this,私有方法和 super所調(diào)用的方法是采用 invokespecial 指令的,也就是根據(jù)引用類型決定調(diào)用的目標(biāo)方法。

    其他更多時(shí)候是用 invokevirtual 指令,不細(xì)究這個(gè)了。希望以上的說(shuō)明能幫助大家的理解。  回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方[未登錄] 2008-07-22 13:41 zxbyh

    ChildClass cc = new SunziClass();
    cc.ff();
    ----------
    最后執(zhí)行到Father類里面的
    public void run(){
    System.out.println("FatherClass.run():"+this.value);
    }
    這里面的this是引用的Sunzi對(duì)象,為什么this.value卻是Father的默認(rèn)value值0呢?
    ------------------------------------------------------------
    這兒實(shí)際上在Sunzi類里面是覆蓋了父類的Public int value 成員變量了,一般來(lái)說(shuō)應(yīng)該設(shè)置成一個(gè)Private 成員變量,然后寫getter和setter來(lái)訪問.

    一般不推薦直接覆蓋父類的Public 成員變量,這個(gè)在C#里面是編譯不能通過的.
    Java里面能通過,但是出現(xiàn)這樣匪夷所思的結(jié)果. 我也不知道是怎么回事情了,
    難道調(diào)用方法的this和調(diào)用成員變量的this不是一個(gè)??好像不可能啊??
    那位高手幫忙解釋一下啦??  回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-22 14:36 zxbyh

    困惑了半天,
    然后看到這一篇文章頓時(shí)茅塞頓開:
    http://www.sudu.cn/info/html/edu/jsp/20071109/102484.html

    原來(lái)對(duì)象的成員變量在Java里面是允許override的.
    但是成員變量是在編譯的時(shí)候決定,但是方法是在運(yùn)行時(shí)決定.
    方法可以動(dòng)態(tài)綁定,但是成員變量不可以動(dòng)態(tài)綁定,如果要讓成員變量實(shí)現(xiàn)動(dòng)態(tài)綁定,那么就需要通過方法.

    還是上面那段代碼,在Main方法里面加上如下
    FatherClass fc1 = new SunziClass();
    fc1.f();
    //加上下面的這一段話:
    System.out.println(fc1.value);
    System.out.println(((SunziClass)fc1).value);

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


    怪不得C#里面不允許Override成員變量
      回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-22 16:56 隔葉黃鶯

    很顯然你應(yīng)該規(guī)避這種問題的出現(xiàn),既然父類中有一個(gè)公有的屬性,子類就應(yīng)該直接繼承這個(gè)屬性,再次聲明一個(gè)同名的公有屬性的意義何在。

    這種問題可能也就能拿來(lái)做面試題,不過我找工作都不愿意做筆記題的,心里抵制這種面試方式。  回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方[未登錄] 2008-07-22 21:31 zxbyh

    個(gè)人還是覺得Java應(yīng)該不允許override public成員變量.
    直接讓他編譯不能通過還還好點(diǎn)...

    腦袋想大了都想不出這樣有何意義,既然是不規(guī)范的東西,何不盡早不讓他發(fā)生.
    就像C#那樣,編譯都通不過!!  回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-22 22:53 fwy

    @zxbyh
    你好,我還是沒能理解最后
    System.out.println("FatherClass.run():"+this.value);
    this確實(shí)是Sunzi對(duì)象,this.value是如何找到Father里面的value的?

      回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-23 12:40 zhuxing

    寫的挺不錯(cuò)的,就是有點(diǎn)亂~_~
    再重新組織一下思路  回復(fù)  更多評(píng)論   

    # re: 關(guān)于this和super有必要理解清楚的地方 2008-07-25 00:58 stanleyxu

    Your example makes beginners really confused. Because you showed a bad logic, why a FatherClass variable should create an ChildClass instance. I suggest you use vehicle, auto, suv, truck, etc.  回復(fù)  更多評(píng)論   


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 免费无码又爽又刺激一高潮| 最近免费中文字幕大全视频| 亚洲黄色高清视频| 成人免费毛片观看| 国产免费久久精品丫丫| 亚洲精品人成电影网| 啊v在线免费观看| 67194国产精品免费观看| 精品久久久久久久久亚洲偷窥女厕 | 成人精品综合免费视频| 久久亚洲精品成人综合| 色播在线永久免费视频| 久久精品成人免费看| 亚洲AV日韩AV无码污污网站 | 亚洲人成电影网站色| 狠狠色伊人亚洲综合成人| 国内一级一级毛片a免费| a级成人毛片免费图片| 亚洲 日韩 色 图网站| 亚洲AV无码久久精品狠狠爱浪潮| 成年性生交大片免费看| 国内精品久久久久影院免费| 日本亚洲高清乱码中文在线观看| 久久亚洲中文字幕精品有坂深雪 | 亚洲av产在线精品亚洲第一站| 国产亚洲成归v人片在线观看 | 亚洲高清无在码在线无弹窗 | 亚洲精品无码成人| 日韩亚洲AV无码一区二区不卡| 亚洲av片一区二区三区| 午夜福利不卡片在线播放免费| 国产一二三四区乱码免费| 亚洲欧美乱色情图片| 亚洲精品美女久久久久| 亚洲AV综合色区无码另类小说| 免费人成网站在线高清| 成年女人18级毛片毛片免费 | 中文字幕在亚洲第一在线| 国产一区二区三区在线免费观看 | 亚洲综合无码AV一区二区| 国产真实伦在线视频免费观看|