十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
目錄:
為北京等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及北京網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、北京網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
【C#小知識】C#中一些易混淆概念總結(jié)--------數(shù)據(jù)類型存儲位置,方法調(diào)用,out和ref參數(shù)的使用
【C#小知識】C#中一些易混淆概念總結(jié)(六)---------解析里氏替換原則,虛方法
-----------------------------------------分割線----------------------------------------------
我筆記本上C#方面的知識基本上整理的差不多了,所以這個關(guān)于《C#小知識》的系列估計(jì)就要完結(jié)了,這個過程中謝謝大家一直來對于我的支持,你們給我的寶貴的意見對我?guī)椭艽蟆?/p>
在介紹抽象類和抽象方法之前還是先提一下多態(tài)的基本概念。
其實(shí)在上一篇關(guān)于里氏替換原則就已經(jīng)說明了多態(tài)的精髓“子類對象可以替換父類對象的位置,而程序的功能不受影響”。還是來看一段代碼吧:
////// Create By:ZhiQiang /// Create Time:2014-2-9 /// class Person { //定義虛方法以備子類重寫,當(dāng)子類替換父類對象的位置時,可以表現(xiàn)出多態(tài) public virtual void Run() { Console.WriteLine("我是人,我會跑!"); } public virtual void Say() { Console.WriteLine("我是人,我會說話!"); } }
子類的代碼如下:
//定義Teacher類繼承Person class Teacher:Person { public override void Run() { Console.WriteLine("我是老師,我必須慢速跑"); } public override void Say() { Console.WriteLine("我是老師,我得說表揚(yáng)的話!"); } } //定義Student類繼承Person class Student : Person { //子類重寫了父類的虛方法 public override void Run() { Console.WriteLine("我是學(xué)生,我會加速跑!"); } public override void Say() { Console.WriteLine("我是學(xué)生,我會說英語!"); } }
下面需要一個實(shí)現(xiàn)多態(tài)的類,代碼如下:
//實(shí)現(xiàn)多態(tài)的類 class FeatureHuman { ////// 這個方法就提現(xiàn)了多態(tài),當(dāng)傳入的是子類的對象的時候,p指向的是子類對象,就可以調(diào)用子類重寫父類方法后的方法 /// /// 父類或者子類對象 public void OutPutFeature(Person p) { p.Run(); p.Say(); } }
主體代碼和實(shí)現(xiàn)多態(tài)的方法如下:
static void Main(string[] args) { FeatureHuman fea = new FeatureHuman(); //人的特點(diǎn) Person p = new Person(); Program pro = new Program(); fea.OutPutFeature(p); //學(xué)生的特點(diǎn) Student s = new Student(); fea.OutPutFeature(s); //老師的特點(diǎn) Teacher t = new Teacher(); fea.OutPutFeature(t); Console.ReadKey(); }
運(yùn)行,打印結(jié)果如下:
這里可以發(fā)現(xiàn),我們outputFeature方法根據(jù)傳入的實(shí)體對象不同(父類變量指向了子類的對象),而打印出了不同人物的特點(diǎn),這就是多態(tài)。
代碼圖解如下:
多態(tài)總結(jié)如下:
二,抽象類和抽象方法
在C#中使用abstract關(guān)鍵字修飾的類和方法,叫做抽象類和抽象方法。
1)抽象類中可以擁有沒抽象成員,為了繼承給他的子類調(diào)用 (抽象類就是為了定義抽象成員,繼承給子類去實(shí)現(xiàn),同時子類也可以調(diào)用父類的非抽象成員)
abstract class Person { //private int nAge; //abstract string strName; //抽象類可以包含不抽象的成員,可以給繼承的子類使用 public void Say() { Console.WriteLine("我是父類,我是人!"); } public virtual void Sing() { Console.WriteLine("我是父類,我是人,我可以唱歌!"); } //Run的抽象方法 public abstract void Run(); }
2)抽象類中可以有virtual修飾的虛方法
如上面的代碼,在抽象類中定義了virtual修飾的方法,編譯通過。抽象類就是為了定義抽象成員,繼承給子類去實(shí)現(xiàn),所以子類也可以實(shí)現(xiàn)抽象類中的虛方法。
3)抽象類不能實(shí)例化,因?yàn)橛谐橄蟪蓡T,而抽象成員沒有方法體,如下圖,
4)抽象成員不能私有,如果私有子類沒有辦法訪問
我們可以在抽象類中定義私有成員,但是沒有意義。因?yàn)樽宇惛驹L問不到這些私有成員,而抽象類本身也不能實(shí)例化,所以私有成員訪問不到。
5)子類必須重寫父類的抽象方法
在上面代碼的基礎(chǔ)上,我們定義一個Student類,繼承抽象類,但是不實(shí)現(xiàn)抽象類的抽象方法,編譯報錯。代碼如下:
6)在子類中沒有辦法通過base關(guān)鍵字調(diào)用父類抽象方法
原理同上,抽象類的抽象發(fā)放沒有實(shí)現(xiàn)語句,就算調(diào)用也沒有意義。但是可以使用base關(guān)鍵字調(diào)用非抽象方法,代碼如下:
class Program { static void Main(string[] args) { //Person p = new Person(); Student s = new Student(); s.Run(); Console.ReadLine(); } } class Student : Person { public override void Run() { base.Say(); Console.WriteLine("我是學(xué)生,繼承了父類,我可以跑!"); } }
打印結(jié)果如下:
抽象類思維導(dǎo)圖總結(jié)如下:
抽象方法
1)抽象方法必須定義在抽象類中,
class Student : Person { public abstract void Swiming(); public override void Run() { base.Say(); Console.WriteLine("我是學(xué)生,繼承了父類,我可以跑!"); } }
代碼編譯會報錯,如下圖:
2)抽象方法必須使用關(guān)鍵字修飾,示例代碼如下:
abstract class Person { //private int nAge; //abstract string strName; //抽象類可以包含不抽象的成員,可以給繼承的子類使用 public void Say() { Console.WriteLine("我是父類,我是人!"); } public virtual void Sing() { Console.WriteLine("我是父類,我是人,我可以唱歌!"); } //Run的抽象方法,不能有方法體,留給子類實(shí)現(xiàn) public abstract void Run();
抽象方法思維導(dǎo)圖總結(jié)如下:
那么什么時候使用抽象類呢?
①子類必須重寫父類的方法(相當(dāng)于定義了一個標(biāo)準(zhǔn),規(guī)范)
②父類沒有必要實(shí)例化,就用抽象類
③抽象類是為了繼承,為了多態(tài)
最后來看一個示例代碼:
定義一個抽象類,其中包含抽象方法Run()
abstract class Person {//Run的抽象方法,只要是繼承我的子類都要實(shí)現(xiàn)這個方法 public abstract void Run(); }
分別定義兩個子類,繼承抽象類Person
class Student : Person { //public abstract void Swiming(); public override void Run() { // base.Say(); Console.WriteLine("我是學(xué)生,繼承了父類,我可以跑!"); } } class Worker:Person { public override void Run() { Console.WriteLine("我是工人,繼承了父類,我每天在廠區(qū)跑!"); } }
為了表現(xiàn)多態(tài),我們編寫一個方法如下:
//該方法變現(xiàn)了多態(tài),根據(jù)需要返回子類的對象 public static Person GetEntity(string str) { if(str=="學(xué)生") { return new Student(); } else if(str=="工人") { return new Worker(); } return null; }
main函數(shù)中的代碼如下:
static void Main(string[] args) { //不直接實(shí)例化父類對象,只是聲明一個父類對象的變量來接收方法的返回值 Person p = GetEntity(Console.ReadLine()); p.Run(); Console.ReadLine(); }
運(yùn)行,分別輸入“工人”和“學(xué)生”的打印結(jié)果如下:
到這里這一部分的內(nèi)容就結(jié)束了,希望大家多多提寶貴的意見。
如果您覺得不錯,點(diǎn)擊右下角贊一下吧!您的支持,是我寫作的動力!
畢業(yè)實(shí)習(xí)交流群:221376964。你也可以關(guān)注我的新浪微博進(jìn)行交流。