成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

目錄:

創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的桃江網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

【C#小知識(shí)】C#中一些易混淆概念總結(jié)--------數(shù)據(jù)類型存儲(chǔ)位置,方法調(diào)用,out和ref參數(shù)的使用

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(二)--------構(gòu)造函數(shù),this關(guān)鍵字,部分類,枚舉

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(三)--------結(jié)構(gòu),GC回收,靜態(tài)成員,靜態(tài)類

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(四)---------解析Console.WriteLine()

----------------------------------分割線--------------------------------------

這次主要分享的內(nèi)容是關(guān)于繼承的知識(shí)。

首先,我們先來(lái)看看繼承;

既然有繼承,就要有父類和子類,來(lái)看下面的一段代碼:

class Person
    {
        private int nAge;
        protected string strName;
        double douHeight;
        public string strEateType;
        public void Hello()
        {
            Console.WriteLine("我可以說Hello!");
        }
        public void Run()
        {
            Console.WriteLine("我可以跑!");
        }
    }
    class Student : Person
    {
    }

然后我在Main()函數(shù)中實(shí)例化子類的對(duì)象,代碼如下:

staticvoid Main(string[] args)        

{        

   Student stu1= new Student();    

  }

那么在這個(gè)過程中內(nèi)存中發(fā)生了些什么呢?

我們先來(lái)看misl的中間代碼,看看那能發(fā)現(xiàn)些什么

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

由此我們可以發(fā)現(xiàn)子類繼承了父類的所有成員包括Private和Protect,并為這些成員開辟了空間來(lái)存儲(chǔ)。

我們?cè)賮?lái)實(shí)例化我們的子類,然后訪問父類的字段和方法,會(huì)發(fā)現(xiàn),如下的現(xiàn)象

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

所以雖然子類為父類的所有成員在堆中都開辟了空間,但是父類的私有成員(Private)子類訪問不到,

而受保護(hù)的成員(protected)可以通過實(shí)例化對(duì)象訪問的到。

所以在內(nèi)存中的情況如下圖:

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

看下面的代碼,我們來(lái)探究一下在子類中this關(guān)鍵字和base關(guān)鍵字所訪問的類的成員有哪些,代碼如下:

class Student : Person
    {
        private string strClass;
        private string strAddress;
        public void Address(string cla, string adre)
        {
            //這里的this關(guān)鍵字調(diào)用了子類的成員和父類的非似有成員
            this.strClass = "五";
            this.strAddress = "北京";
            this.strName = "子強(qiáng)";
            //這里base關(guān)鍵字調(diào)用了是父類的非似有成員
            base.strName = "強(qiáng)子";
            Console.WriteLine("我是{0}年紀(jì),來(lái)自{1}", cla, adre);
        }
        public void Sing()
        {
            this.strClass = "";
            Console.WriteLine("我可以唱歌!");
        }
    }

所以在子類中this關(guān)鍵字和base關(guān)鍵字的訪問范圍的示意圖如下:

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

二,關(guān)于子類對(duì)象的構(gòu)造函數(shù)和父類構(gòu)造函數(shù)的執(zhí)行順序

我們分別為父類和子類添加顯式的構(gòu)造函數(shù),代碼如下

class Person
    {
        private int nAge;
        protected string strName;
        double douHeight;
        public string strEateType;
        //父類的構(gòu)造函數(shù)
        public Person()
        {
            Console.WriteLine("我是父類的構(gòu)造函數(shù)");
        }
        public void Hello()
        {
            Console.WriteLine("我可以說Hello!");
        }
        public void Run()
        {
            Console.WriteLine("我可以跑!");
        }
    }
    class Student : Person
    {
        private string strClass;
        private string strAddress;
        //子類的構(gòu)造函數(shù)
        public Student ()
        {
            Console.WriteLine("我是子類的構(gòu)造函數(shù)");
        }
    }

我們使用VS的單步調(diào)試,來(lái)看父類和子類顯式構(gòu)造函數(shù)的執(zhí)行順序,如下圖(動(dòng)態(tài)圖片,可以看到過程):

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

很容易的可以發(fā)現(xiàn),當(dāng)創(chuàng)建子類對(duì)象的時(shí)候

①先調(diào)用了子類的構(gòu)造函數(shù)

②調(diào)用了父類的構(gòu)造函數(shù)

③執(zhí)行了父類的構(gòu)造函數(shù)

④執(zhí)行了子類的構(gòu)造函數(shù)

那么為什么會(huì)這樣呢?

我嘗試通過反編譯看源碼來(lái)解釋這個(gè)原因,但是反編譯的結(jié)果如下,

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

沒有發(fā)現(xiàn)有什么特別的地方可以解釋這個(gè)原因。

最后還是查閱微軟的MSDN官方文檔找到了答案(原文地址點(diǎn)擊這里)

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

根據(jù)微軟官方的代碼示例,那么下面的代碼的效果也是相同的

//子類的構(gòu)造函數(shù)
        public Student ()
        {
            Console.WriteLine("我是子類的構(gòu)造函數(shù)");
        }
//這里的代碼和上面的代碼效果是相同的
        public Student()
            :base()
        {
            Console.WriteLine("我是子類的構(gòu)造函數(shù)");
        }

也就是說只要在子類顯式的聲明了無(wú)參的構(gòu)造函數(shù),在實(shí)例化子類的對(duì)象是,子類的無(wú)參構(gòu)造函數(shù)都會(huì)去調(diào)用父類無(wú)參的構(gòu)造函數(shù)。

那么,如果父類沒有這個(gè)無(wú)參的構(gòu)造函數(shù)則會(huì)報(bào)錯(cuò)。

如下面的代碼:

class Person
    {
        private int nAge;
        protected string strName;
        double douHeight;
        public string strEateType;
        //父類的構(gòu)造函數(shù)
        //public Person()
        //{
        //    Console.WriteLine("我是父類的構(gòu)造函數(shù)");
        //}
      //父類的有參數(shù)的構(gòu)造函數(shù),這里覆蓋了無(wú)參的構(gòu)造函數(shù)
        public Person (string str)
        {
            Console.WriteLine("我是父類的構(gòu)造函數(shù){0}",str);
        }
        public void Hello()
        {
            Console.WriteLine("我可以說Hello!");
        }
        public void Run()
        {
            Console.WriteLine("我可以跑!");
        }
    }
    class Student : Person
    {
        private string strClass;
        private string strAddress;
        //子類的無(wú)參構(gòu)造函數(shù)
        public Student ()
        {
            Console.WriteLine("我是子類的構(gòu)造函數(shù)");
        }
        public Student(string strName)
        {
            Console.WriteLine("我的名字叫{0}",strName);
        }
    }

這時(shí)候編譯會(huì)報(bào)錯(cuò),

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

因?yàn)樵诟割愔杏袇?shù)的構(gòu)造函數(shù)覆蓋了無(wú)參數(shù)的構(gòu)造函數(shù),所以在子類的無(wú)參數(shù)的構(gòu)造函數(shù)沒辦法回調(diào)父類的無(wú)參數(shù)的構(gòu)造函數(shù)初始化父類的成員變量。所以報(bào)錯(cuò)。

那么在初始化子類的時(shí)候,為什么要調(diào)用父類的構(gòu)造函數(shù)呢?

在初始化子類之前需要通過構(gòu)造函數(shù)初始化父類的成員變量

父類的構(gòu)造函數(shù)先于子類的構(gòu)造函數(shù)執(zhí)行的意義是什么呢?

當(dāng)在父類的構(gòu)造函數(shù)中和子類的構(gòu)造函數(shù)中為父類的非私有成員變量賦不同默認(rèn)值。當(dāng)實(shí)例化子類,子類要調(diào)用構(gòu)造函數(shù)初始化成員變量,如果先執(zhí)行了子類的構(gòu)造函數(shù),再執(zhí)行父類的構(gòu)造函數(shù),父類成員字段的值會(huì)覆蓋子類成員字段的值。但是我們想得到的是子類的屬性值。所以為了解決數(shù)據(jù)沖突,父類的構(gòu)造函數(shù)要先于子類的構(gòu)造函數(shù)執(zhí)行。

如下面的代碼:

class Person
    {
        private int nAge;
        private string strName;
        double douHeight;
        public string strEateType;
       // 父類的構(gòu)造函數(shù)
        public Person()
        {
            //再父類中對(duì)strEateType賦初始值
            this.strEateType = "吃飯";
            Console.WriteLine("我是父類的構(gòu)造函數(shù){0}", strEateType);
        }
    }
    class Student : Person
    {
        private string strClass;
        private string strAddress;
        //子類的構(gòu)造函數(shù)
        public Student()
        {
            //在子類中對(duì)strEateType賦初始值
            this.strEateType = "吃面條";
            Console.WriteLine("我是子類的構(gòu)造函數(shù){0}",strEateType);
        }
    }

這時(shí)候我們通過,聲明子類對(duì)象訪問strEateType的值,如下:

Student stu1 = new Student();
            //stu1.
            string str = stu1.strEateType.ToString();
            Console.WriteLine(str);
            Console.ReadKey();

這里肯定是要打印出子類的屬性strEateType的值,如果先執(zhí)行子類構(gòu)造函數(shù)對(duì)strEateType賦值,然后父類的構(gòu)造函數(shù)賦值覆蓋strEateType的初始值。那么打印出的將是父類成員字段的值。所以,父類的構(gòu)造函數(shù)先于子類的構(gòu)造函數(shù)執(zhí)行。

打印結(jié)果如下:

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

三,子類是否可以有和父類的同名方法

看下面的代碼,我們聲明一個(gè)父類Person:

class Person
    {
        private int nAge;
        private string strName;
        double douHeight;
        public string strEateType;
       public  readonly string strrrr;
        // 父類的構(gòu)造函數(shù)
        public Person()
        {
            this.strEateType = "吃飯";
            Console.WriteLine("我是父類的構(gòu)造函數(shù){0}", strEateType);
        }
        public Person(string str)
        {
            this.strName = str;
            Console.WriteLine("我是父類的構(gòu)造函數(shù){0}", str);
        }
        public void Hello()
        {
            Console.WriteLine("我可以說地球人的Hello!");
        }
        public void Run()
        {
            Console.WriteLine("我可以跑!");
        }
    }

聲明一個(gè)子類繼承Person,代碼如下:

class Worker:Person
    {
        public void  Hello()
        {
            Console.WriteLine("我是工人會(huì)說Hello!");
        }
        public new void  Run()
        {
            Console.WriteLine("我是工人我會(huì)奔跑!");
        }
    }

然后實(shí)例化Worker對(duì)象,打印Hello方法,結(jié)果如下圖:

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

這是為什么呢?編譯器已經(jīng)告訴了我們,如下圖:

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承


看出來(lái)是子類的方法隱藏了父類的方法。

既然子類可以定義和父類同名的方法,那么是否可以定同名的字段呢?答案是肯定的,而且會(huì)像同名方法一樣,子類同名字段會(huì)隱藏父類同名的字段。


如果您覺得不錯(cuò),點(diǎn)擊右下角贊一下吧!您的支持,是我寫作的動(dòng)力!

畢業(yè)實(shí)習(xí)交流群:221376964。你也可以關(guān)注我的新浪微博進(jìn)行交流。

【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承

新聞標(biāo)題:【C#小知識(shí)】C#中一些易混淆概念總結(jié)(五)---------深入解析C#繼承
標(biāo)題URL:http://jinyejixie.com/article30/ppegpo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、電子商務(wù)、云服務(wù)器、微信小程序、Google、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)
西丰县| 宁安市| 久治县| 潞西市| 榕江县| 七台河市| 西安市| 财经| 微博| 财经| 普定县| 应城市| 调兵山市| 阳信县| 牡丹江市| SHOW| 芷江| 高雄市| 大荔县| 东兰县| 凤山市| 崇阳县| 大城县| 怀集县| 定州市| 滨州市| 桂平市| 托里县| 唐海县| 会昌县| 西充县| 绥江县| 汽车| 定州市| 乌兰浩特市| 桐乡市| 城固县| 鸡泽县| 河东区| 巴彦淖尔市| 桐梓县|