日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

繼承本質(zhì)論

系統(tǒng) 2234 0

1 .對象的創(chuàng)建過程

Bird bird 創(chuàng)建的是一個(gè) Bird 類型的引用,而 new Bird () 完成的是創(chuàng)建 Bird 對象,分配內(nèi)存空間和初始化操作,然后將這個(gè)對象引用賦給 bird 變量,也就是建立 bird 變量與 Bird 對象的關(guān)聯(lián)。

2 .從繼承的角度分析對象的創(chuàng)建過程

在此我們以 Chicken 對象的創(chuàng)建為例,首先是字段,對象一經(jīng)創(chuàng)建,會(huì)首先找到其父類 Bird ,并為其字段分配存儲(chǔ)空間,而 Bird 也會(huì)繼續(xù)找到其父類 Animal ,為其分配存儲(chǔ)空間,依次類推直到遞歸結(jié)束,也就是完成 System.Object 內(nèi)存分配為止。

思考

通過上面的講述與分析,我們基本上對 .NET 在編譯期的實(shí)現(xiàn)原理有了大致的了解,但是還有以下的問題,一定會(huì)引起一定的疑惑,那就是: Bird bird2 = new Chicken();

這種情況下, bird2.ShowType 應(yīng)該返回什么值呢?而 bird2.type 又該是什么值呢?有兩個(gè)原則,是 .NET 專門用于解決這一問題的:

關(guān)注對象原則: 調(diào)用子類還是父類的方法,取決于創(chuàng)建的對象是子類對象還是父類對象,而不是它的引用類型。例如 Bird bird2 = new Chicken() 時(shí),我們關(guān)注的是其創(chuàng)建對象為 Chicken 類型,因此子類將繼承父類的字段和方法,或者覆寫父類的虛方法,而不用關(guān)注 bird2 的引用類型是否為 Bird 引用類型不同的區(qū)別決定了不同的對象在方法表中不同的訪問權(quán)限。

注意: 根據(jù)關(guān)注對象原則,那么下面的兩種情況又該如何區(qū)別呢?

Bird bird = new Chicken ();

Chicken chicken = new Chicken ();

根據(jù)我們上文的分析, bird 對象和 chicken 對象在內(nèi)存布局上是一樣的,差別就在于其引用指針的類型不同: bird Bird 類型指針,而 chicken Chicken 類型指針。以方法調(diào)用為例,不同的類型指針在虛擬方法表中有不同的附加信息作為標(biāo)志來區(qū)別其訪問的地址區(qū)域,稱為 offset 。不同類型的指針只能在其特定地址區(qū)域內(nèi)進(jìn)行執(zhí)行,子類覆蓋父類時(shí)會(huì)保證其訪問地址區(qū)域的一致性,從而解決了不同的類型訪問具有不同的訪問權(quán)限問題。

執(zhí)行就近原則: 對于同名字段或者方法,編譯器是按照其順序查找來引用的,也就是首先訪問離它創(chuàng)建最近的字段或者方法,例如上例中的 bird ,是 Bird 類型,因此會(huì)首先訪問 Bird_type (注意編譯器是不會(huì)重新命名的,在此是為區(qū)分起見),如果 type 類型設(shè)為 public ,則在此將返回 Bird 值。這也就是為什么在對象創(chuàng)建時(shí)必須將字段按順序排列,而父類要先于子類編譯的原因了。

繼承本質(zhì)論

// 經(jīng)典指令解析之方法調(diào)度

using System;

using System.Collections.Generic;

using System.Text;

namespace testCall

{

public class Father

{

public void DoWork()

{

Console .WriteLine( "Father.DoWork()" );

}

public virtual void DoVirtualWork()

{

Console .WriteLine( "Father.DoVirtualWork()" );

}

public virtual void DoVirtualAll()

{

Console .WriteLine( "Father.DoVirtualAll()" );

}

}

public class Son : Father

{

public static void DoStaticWork()

{

Console .WriteLine( "Son.DoStaticWork()" );

}

public new void DoWork()

{

Console .WriteLine( "Son.DoWork()" );

}

public new virtual void DoVirtualWork()

{

base .DoVirtualWork();

Console .WriteLine( "Son.DoVirtualWork()" );

}

public override void DoVirtualAll()

{

Console .WriteLine( "Son.DoVirtualAll()" );

}

}

public class Grandson : Son

{

public override void DoVirtualWork()

{

base .DoVirtualWork();

Console .WriteLine( "Grandson.DoVirtualWork()" );

}

public override void DoVirtualAll()

{

base .DoVirtualAll();

Console .WriteLine( "Grandson.DoVirtualAll()" );

}

}

// 方法調(diào)用測試類

class call

{

static void Main( string [] args)

{

Father son = new Son ();

son.DoWork(); // 調(diào)用 Father.DoWork()

son.DoVirtualWork(); // 調(diào)用 Father.DoVirtualWork()

Son .DoStaticWork(); // 調(diào)用 Son 類特有的靜態(tài)方法 DoStaticWork()

Father aGrandson = new Grandson ();

aGrandson.DoWork(); // 調(diào)用 Father.DoWork()

aGrandson.DoVirtualWork(); // 調(diào)用 Father.DoVirtualWork()

aGrandson.DoVirtualAll(); // 調(diào)用 Grandson.DoVirtualAll()

Console .ReadKey();

}

}

}

new 隱藏基類成員中同名的成員方法,也就是該方法獨(dú)立于基類的方法。派生類同名方法如果未定義為 new override 則默認(rèn)定義為 new 的方法。

override 表示覆寫,顯式的重寫基類成員,以實(shí)現(xiàn)派生類自己的版本。 C++ 派生類中對同名的基類方法的覆寫只需將基類方法聲明為 virtual

Son 中定義的 new DoWork() 獨(dú)立于 Father 中定義的同名的 DoWork() 方法,對于 Son 對象繼承的 DoWork() 方法被 new 隱藏而不可見。而 override DoVirtualAll() 則生成自己版本的 DoVirtualAll() 方法。

繼承本質(zhì)論

根據(jù)以上示意圖很容易分析出以上測試代碼的結(jié)果。

說明:

本文摘自《你必須知道的 .NET 》第十五回《繼承本質(zhì)論》,有改動(dòng)。

http://www.cnblogs.com/anytao/archive/2007/09/10/must_net_15.html

繼承本質(zhì)論


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 宁安市| 衡阳县| 安庆市| 余江县| 福州市| 揭西县| 锦州市| 盐山县| 刚察县| 布拖县| 仁化县| 长海县| 遵义县| 洮南市| 甘德县| 吴川市| 罗平县| 太湖县| 万安县| 泽库县| 桓仁| 阿巴嘎旗| 清镇市| 竹北市| 连云港市| 红原县| 仁布县| 平定县| 淮安市| 安丘市| 古田县| 安福县| 潞城市| 罗江县| 廉江市| 巴林左旗| 曲周县| 合江县| 白城市| 禹州市| 桐乡市|