亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

深入理解OOP(三):多態和繼承(動態綁定和運行時多態)

2019-11-14 13:36:28
字體:
來源:轉載
供稿:網友
在前面的文章中,我們介紹了編譯期多態、params關鍵字、實例化、base關鍵字等。本節我們來關注另外一種多態:運行時多態, 運行時多態也叫遲綁定。
  • 深入理解OOP(一):多態和繼承(初期綁定和編譯時多態)

  • 深入理解OOP(二):多態和繼承(繼承)

  • 深入理解OOP(三):多態和繼承(動態綁定和運行時多態)

  • 深入理解OOP(四):多態和繼承(C#中的抽象類)

  • 深入理解OOP(五):C#中的訪問修飾符(Public/PRivate/Protected/Internal/Sealed/Constants/Static and Readonly Fields)

  • 深入理解OOP(六):枚舉(實用方法)

  • 深入理解OOP(七):屬性(實用方法)

  • 深入理解OOP(八):索引器(實用方法)

  • 深入理解OOP(九):事件(深入理解)


 

運行時多態或遲綁定、動態綁定

 在C#語音中,運行時多態也叫方法重寫(overriding),我們可以在子類中overriding基類的同簽名函數,使用“virtual & override”關鍵字即可。

 


 

C#的New、Override關鍵字

創建一個console 示例工程,命名為InheritanceAndPolymorphism。在Program.cs基礎上,再添加2個類文件,分別命名為ClassA.cs、ClassB.cs。拷貝如下代碼:

public class ClassA    {        public void AAA()        {            Console.WriteLine("ClassA AAA");        }        public void BBB()        {            Console.WriteLine("ClassA BBB");        }        public void CCC()        {            Console.WriteLine("ClassA CCC");        }    }

 

ClassB:

public class ClassB    {        public void AAA()        {            Console.WriteLine("ClassB AAA");        }        public void BBB()        {            Console.WriteLine("ClassB BBB");        }        public void CCC()        {            Console.WriteLine("ClassB CCC");        }    }

在上面的代碼中,我們可以看到ClassA、ClassB有同樣簽名的方法,可以在program.cs中直接使用。

我們對代碼再做休整,結構如下:

/// <summary>    /// ClassB, acting as a base class    /// </summary>    public class ClassB    {        public void AAA()        {            Console.WriteLine("ClassB AAA");        }        public void BBB()        {            Console.WriteLine("ClassB BBB");        }        public void CCC()        {            Console.WriteLine("ClassB CCC");        }    }    /// <summary>    /// Class A, acting as a derived class    /// </summary>    public class ClassA : ClassB    {        public void AAA()        {            Console.WriteLine("ClassA AAA");        }        public void BBB()        {            Console.WriteLine("ClassA BBB");        }        public void CCC()        {            Console.WriteLine("ClassA CCC");        }    }

Program.cs

/// <summary>    /// Program: used to execute the method.    /// Contains Main method.    /// </summary>    public class Program    {        private static void Main(string[] args)        {            ClassA x = new ClassA();            ClassB y=new ClassB();            ClassB z=new ClassA();            x.AAA(); x.BBB(); x.CCC();            y.AAA(); y.BBB();y.CCC();            z.AAA(); z.BBB(); z.CCC();        }    }

F5,運行代碼,結果如下:

ClassA AAA

ClassA BBB

ClassA CCC

ClassB AAA

ClassB BBB

ClassB CCC

ClassB AAA

ClassB BBB

ClassB CCC

 

但同時,在VS的Output窗口,我們獲得了3個Warnings:

'InheritanceAndPolymorphism.ClassA.AAA()' hides inherited member

'InheritanceAndPolymorphism.ClassB.AAA()'. Use the new keyWord if hiding was intended.

'InheritanceAndPolymorphism.ClassA.BBB()' hides inherited member

'InheritanceAndPolymorphism.ClassB.BBB()'. Use the new keyword if hiding was intended.

'InheritanceAndPolymorphism.ClassA.CCC()' hides inherited member

'InheritanceAndPolymorphism.ClassB.CCC()'. Use the new keyword if hiding was intended.

這些Warnings的原因是因為子類和基類的AAA、BBB、CCC方法簽名相同,盡管從執行上看優先執行子類同簽名的方法,但是可能會有潛在的問題,故Warnings提出。

 


重構實驗

基于上面的Warning,我們手動修改代碼,看看如何消除這些Warnings。

 

先給子類添加new、override關鍵字試試:

/// <summary>    /// Class A, acting as a derived class    /// </summary>    public class ClassA : ClassB    {        public override void AAA()        {            Console.WriteLine("ClassA AAA");        }        public new void BBB()        {            Console.WriteLine("ClassA BBB");        }        public void CCC()        {            Console.WriteLine("ClassA CCC");        }    }

執行的結果是報錯了:

Error: 'InheritanceAndPolymorphism.ClassA.AAA()': cannot override inherited member 'InheritanceAndPolymorphism.ClassB.AAA()' because it is not marked virtual, abstract, or override

從這個錯誤提示信息看,我們需要修改基類方法,如添加virtual關鍵字。

/// <summary>    /// ClassB, acting as a base class    /// </summary>    public class ClassB    {        public virtual void AAA()        {            Console.WriteLine("ClassB AAA");        }        public virtual void BBB()        {            Console.WriteLine("ClassB BBB");        }        public virtual void CCC()        {            Console.WriteLine("ClassB CCC");        }    }    /// <summary>    /// Class A, acting as a derived class    /// </summary>    public class ClassA : ClassB    {        public override void AAA()        {            Console.WriteLine("ClassA AAA");        }        public new void BBB()        {            Console.WriteLine("ClassA BBB");        }        public void CCC()        {            Console.WriteLine("ClassA CCC");        }    }    /// <summary>    /// Program: used to execute the method.    /// Contains Main method.    /// </summary>    public class Program    {        private static void Main(string[] args)        {            ClassB y = new ClassB();            ClassA x = new ClassA();            ClassB z = new ClassA();            y.AAA(); y.BBB(); y.CCC();            x.AAA(); x.BBB(); x.CCC();            z.AAA(); z.BBB(); z.CCC();            Console.ReadKey();        }    }

執行,則無Warning了,通過這個實例,我們得知通過在基類添加Virtual關鍵字授權其子類可override基類同簽名方法的權限,方便了OOP的擴展。

 


3個類的運行時多態

/// <summary>    /// ClassB, acting as a base class    /// </summary>    public class ClassB    {        public  void AAA()        {            Console.WriteLine("ClassB AAA");        }        public virtual void BBB()        {            Console.WriteLine("ClassB BBB");        }        public virtual void CCC()        {            Console.WriteLine("ClassB CCC");        }    }    /// <summary>    /// Class A, acting as a derived class    /// </summary>    public class ClassA : ClassB    {        public virtual void AAA()        {            Console.WriteLine("ClassA AAA");        }        public new void BBB()        {            Console.WriteLine("ClassA BBB");        }        public override void CCC()        {            Console.WriteLine("ClassA CCC");        }    }    /// <summary>    /// Class C, acting as a derived class    /// </summary>    public class ClassC : ClassA    {        public override void AAA()        {            Console.WriteLine("ClassC AAA");        }        public void CCC()        {            Console.WriteLine("ClassC CCC");        }    }    /// <summary>    /// Program: used to execute the method.    /// Contains Main method.    /// </summary>    public class Program    {        private static void Main(string[] args)        {            ClassB y = new ClassA();            ClassB x = new ClassC();            ClassA z = new ClassC();            y.AAA(); y.BBB(); y.CCC();            x.AAA(); x.BBB(); x.CCC();            z.AAA(); z.BBB(); z.CCC();            Console.ReadKey();        }    }

運行結果:

ClassB AAA

ClassB BBB

ClassA CCC

ClassB AAA

ClassB BBB

ClassA CCC

ClassC AAA

ClassA BBB

ClassA CCC

 

如果基類聲明了virtual 關鍵字,子類可使用override修飾符實現運行時多態:只有在編譯器動態決定是否被調用。

如果未標明virtual或非virtual,則方法是否被調用在編譯期就能決定。

 

再看看下面的例子:

 

internal class A    {        public virtual void X()        {        }    }    internal class B : A    {        public new void X()        {        }    }    internal class C : B    {        public override void X()        {        }    }

 

F5運行,結果報錯了:

Error: 'InheritanceAndPolymorphism.C.X()': cannot override inherited member 'InheritanceAndPolymorphism.B.X()' because it is not marked virtual, abstract, or override

 

錯誤的原因是A中定義了virtual的X函數,在B中用new關鍵字隱藏了A中的X函數。當C嘗試通過override關鍵字的時候,是獲得不了A中的virtual關鍵字X函數的,既在C中X函數為非Virtual的,故不能override。


切斷關系

internal class A    {        public virtual void X()        {            Console.WriteLine("Class: A ; Method X");        }    }    internal class B : A    {        public new virtual void X()        {            Console.WriteLine("Class: B ; Method X");        }    }    internal class C : B    {        public override void X()        {            Console.WriteLine("Class: C ; Method X");        }    }    /// <summary>    /// Program: used to execute the method.    /// Contains Main method.    /// </summary>    public class Program    {        private static void Main(string[] args)        {            A a = new C();            a.X();            B b = new C();            b.X();            Console.ReadKey();        }    }

執行結果如下:

 

Class: A ; Method XClass: C ; Method X

在這里,我們通過在B類中添加new Virtual修飾符,然后在C中即可使用B中Virtual的X函數了。

 


 

4個類的運行時多態

在上面繼承上,在運行時多態中添加第四個類:ClassD。

/// <summary>    /// Class A    /// </summary>    public class ClassA    {        public virtual void XXX()        {            Console.WriteLine("ClassA XXX");        }    }    /// <summary>    /// ClassB    /// </summary>    public class ClassB:ClassA     {        public override void XXX()        {            Console.WriteLine("ClassB XXX");        }    }    /// <summary>    /// Class C    /// </summary>    public class ClassC : ClassB    {        public virtual new void XXX()        {            Console.WriteLine("ClassC XXX");        }    }    /// <summary>    /// Class D    /// </summary>    public class ClassD : ClassC    {        public override void XXX()        {            Console.WriteLine("ClassD XXX");        }    }    /// <summary>    /// Program: used to execute the method.    /// Contains Main method.    /// </summary>    public class Program    {        private static void Main(string[] args)        {            ClassA a = new ClassD();            ClassB b = new ClassD();            ClassC c=new ClassD();            ClassD d=new ClassD();                       a.XXX();            b.XXX();            c.XXX();            d.XXX();            Console.ReadKey();        }    }

執行結果如下:

ClassB XXX

ClassB XXX

ClassD XXX

ClassD XXX

第一行輸出中,來自a.XXX()函數 , 我們在 ClassA中定義了XXX函數,然后在ClassB中使用new關鍵字切斷了virtual關系--對子類而言。因此XXX函數從ClassC開始成為新的virtual函數,在這個代碼中a是ClassD的實例,但是聲明的為ClassA,故從下往上找,找到ClassB的XXX函數,打印并輸出結果。

 


 

永無止境的循環

/// <summary>    /// Class A    /// </summary>    public class ClassA    {        public virtual void XXX()        {            Console.WriteLine("ClassA XXX");        }    }    /// <summary>    /// ClassB    /// </summary>    public class ClassB:ClassA     {        public override void XXX()        {            ((ClassA)this).XXX();            Console.WriteLine("ClassB XXX");        }    }       /// <summary>    /// Program: used to execute the method.    /// Contains Main method.    /// </summary>    public class Program    {        private static void Main(string[] args)        {            ClassA a = new ClassB();            a.XXX();                   }    }

運行報錯:

Error: {Cannot evaluate expression because the current thread is in a stack overflow state.}

在這個例子中,((ClassA)this).XXX(); 導致了循環調用,修改為base.XXX即可修復這個強轉導致的循環調用。

 


結論

  • 在C#中,子類對象可賦值給一個基類對象;相反需要強轉。

  • override關鍵字用于子類重寫同簽名的基類virtual函數

  • 用new和override可重寫基類virtual的同簽名函數

  • virtual修飾符的函數,只能在運行時決定是否被執行

  • 函數未用virtual修飾,則在編譯期即可決定是否被調用

 

譯文鏈接:http://www.49028c.com/powertoolsteam/p/Diving-in-OOP-Day-Polymorphism-and-Inheritance-Dyn.html

原文鏈接:Diving in OOP (Day 3): Polymorphism and Inheritance (Dynamic Binding/Run Time Polymorphism)

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
2018国产精品视频| 亚洲色图日韩av| 欧美—级a级欧美特级ar全黄| 欧美日韩成人网| 欧美黑人一级爽快片淫片高清| 亚洲福利在线视频| 2021国产精品视频| 亚洲永久免费观看| 欧美日韩999| 欧美激情国产精品| 欧美日本啪啪无遮挡网站| 日韩精品在线观| 日韩在线欧美在线| 成人a在线观看| 91精品久久久久久久久久| 久久躁日日躁aaaaxxxx| 九九视频这里只有精品| 国产精品色悠悠| 亚洲一区美女视频在线观看免费| 午夜精品在线视频| 国产精品久久二区| 欧美怡红院视频一区二区三区| 国产成人在线精品| 国产精品视频午夜| 国产精品麻豆va在线播放| 欧美日韩国产影院| 性欧美长视频免费观看不卡| 欧美美女操人视频| 亚洲精品视频网上网址在线观看| 最近2019中文免费高清视频观看www99| 精品激情国产视频| 91中文字幕在线观看| 日韩精品福利在线| 亚洲高清在线观看| 欧美性生交xxxxxdddd| 91精品国产91久久久久福利| 国产91在线高潮白浆在线观看| 久久久久久久av| 久久久999精品视频| www.色综合| 亚洲男人7777| 亚洲一区二区免费| 欧美精品videofree1080p| 伊人久久精品视频| 久久久国产精品一区| 高清视频欧美一级| 992tv成人免费影院| 一区二区三区回区在观看免费视频| 亚洲精品美女网站| 2019中文字幕全在线观看| 国产精品嫩草影院久久久| 在线精品视频视频中文字幕| 欧美成人四级hd版| www.日本久久久久com.| 日韩av男人的天堂| 国产精品久久久久久久天堂| 亚洲免费视频一区二区| 亚洲精品免费网站| 亚洲国产高清福利视频| 国产精品日韩在线播放| 国产激情999| 欧美专区福利在线| 亚洲精品国产电影| 亚洲 日韩 国产第一| 91po在线观看91精品国产性色| 日韩欧美在线视频观看| 久久久久久久久久久亚洲| 国产婷婷色综合av蜜臀av| 国产精品第一第二| 国产精品一区二区三| 日韩中文字在线| 亚洲欧洲第一视频| 国产97色在线| 成人午夜在线影院| 乱亲女秽乱长久久久| 欧美大成色www永久网站婷| 欧美一级片久久久久久久| 国产欧美亚洲视频| 91精品国产91| 亚洲精品电影久久久| 久久露脸国产精品| 中文字幕国产亚洲| 日本免费在线精品| 97婷婷大伊香蕉精品视频| 久久久久久国产免费| 国产不卡视频在线| 青草青草久热精品视频在线观看| 日韩高清电影好看的电视剧电影| 久久亚洲精品中文字幕冲田杏梨| 国产精品亚洲综合天堂夜夜| 日韩在线播放一区| 久久成人综合视频| 日本19禁啪啪免费观看www| 欧美一区二区色| 亚洲第一精品自拍| 一区二区在线视频| 欧美一级大胆视频| 久久精品色欧美aⅴ一区二区| 亚洲最大福利网站| 久久久999精品| 最近2019好看的中文字幕免费| 狠狠躁18三区二区一区| 日韩在线国产精品| 91美女片黄在线观看游戏| 日韩av电影免费观看高清| 欧美一级免费视频| 欧美孕妇与黑人孕交| 亚洲香蕉成人av网站在线观看| 国语对白做受69| 欧美精品午夜视频| 久久精品久久久久久国产 免费| 亚洲国产成人av在线| 精品国产一区二区三区四区在线观看| 欧美又大又粗又长| 亚洲一区二区中文| 成人性生交xxxxx网站| 国产精品丝袜久久久久久不卡| 国产在线视频91| 国产精品网址在线| 精品精品国产国产自在线| 亚洲日韩中文字幕| 精品福利在线视频| 一区二区三区在线播放欧美| 国产精品成久久久久三级| 精品国模在线视频| 成人疯狂猛交xxx| 91久久国产综合久久91精品网站| 日韩电影中文 亚洲精品乱码| 欧美一级淫片丝袜脚交| 欧美日韩国产一区中文午夜| 九九热99久久久国产盗摄| 国产精品高潮粉嫩av| 亚洲欧美国产视频| 国产精品扒开腿爽爽爽视频| 日韩欧美在线视频观看| 久久久av电影| 亚洲欧美国产视频| 中文字幕日韩精品在线| 中文字幕亚洲欧美日韩2019| 国产日韩精品综合网站| 最新69国产成人精品视频免费| 中文字幕精品国产| 亚洲精品成a人在线观看| 久久精品91久久香蕉加勒比| 欧美国产日韩二区| 国产精品色视频| 懂色av一区二区三区| 日本成人免费在线| 国产精品永久在线| 国产精品国产三级国产专播精品人| 欧美精品情趣视频| 亚洲a级在线播放观看| 91美女福利视频高清| 91精品国产成人| 亚洲欧洲高清在线| 欧美乱大交做爰xxxⅹ性3| 上原亚衣av一区二区三区| 韩国v欧美v日本v亚洲| 久久精品国产v日韩v亚洲| 亚洲欧美日韩高清| 亚洲一区二区三区在线免费观看| 97超碰蝌蚪网人人做人人爽| 亚洲乱码国产乱码精品精天堂| 亚洲精品国精品久久99热一|