鍍金池/ 教程/ C/ 解析抽象類,抽象方法
解析接口
C#中一些易混淆概念總結(jié)-數(shù)據(jù)類型存儲(chǔ)位置,方法調(diào)用,out和ref參數(shù)的使用
解析里氏替換原則,虛方法
繼承
構(gòu)造函數(shù),this關(guān)鍵字,部分類,枚舉
解析Console.WriteLine()
解析抽象類,抽象方法
結(jié)構(gòu),GC回收,靜態(tài)成員,靜態(tài)類

解析抽象類,抽象方法

我筆記本上C#方面的知識(shí)基本上整理的差不多了,所以這個(gè)關(guān)于《C#小知識(shí)》的系列估計(jì)就要完結(jié)了,這個(gè)過程中謝謝大家一直來對(duì)于我的支持,你們給我的寶貴的意見對(duì)我?guī)椭艽蟆?/p>

在介紹抽象類和抽象方法之前還是先提一下多態(tài)的基本概念。

其實(shí)在上一篇關(guān)于里氏替換原則就已經(jīng)說明了多態(tài)的精髓"子類對(duì)象可以替換父類對(duì)象的位置,而程序的功能不受影響"。還是來看一段代碼吧:

/// 

    /// Create By:ZhiQiang
    /// Create Time:2014-2-9
    /// 

    class Person
    {

       //定義虛方法以備子類重寫,當(dāng)子類替換父類對(duì)象的位置時(shí),可以表現(xiàn)出多態(tài)
        public virtual void Run()
        {
            Console.WriteLine("我是人,我會(huì)跑!");
        }

        public virtual void Say()
        {
            Console.WriteLine("我是人,我會(huì)說話!");
        }
    }

子類的代碼如下:

    //定義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é)生,我會(huì)加速跑!");
        }

        public override void Say()
        {
            Console.WriteLine("我是學(xué)生,我會(huì)說英語!");
        }
    }

下面需要一個(gè)實(shí)現(xiàn)多態(tài)的類,代碼如下:

    //實(shí)現(xiàn)多態(tài)的類
    class FeatureHuman
    {
        /// 

        /// 這個(gè)方法就提現(xiàn)了多態(tài),當(dāng)傳入的是子類的對(duì)象的時(shí)候,p指向的是子類對(duì)象,就可以調(diào)用子類重寫父類方法后的方法
        /// 

        /// 父類或者子類對(duì)象
        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é)果如下:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.1.png" alt="" />

這里可以發(fā)現(xiàn),我們outputFeature方法根據(jù)傳入的實(shí)體對(duì)象不同(父類變量指向了子類的對(duì)象),而打印出了不同人物的特點(diǎn),這就是多態(tài)。

代碼圖解如下:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.2.png" alt="" />

多態(tài)總結(jié)如下:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.3.png" alt="" />

二,抽象類和抽象方法

在C#中使用abstract關(guān)鍵字修飾的類和方法,叫做抽象類和抽象方法。

1)抽象類中可以擁有沒抽象成員,為了繼承給他的子類調(diào)用 (抽象類就是為了定義抽象成員,繼承給子類去實(shí)現(xiàn),同時(shí)子類也可以調(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,而抽象成員沒有方法體,如下圖,

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.4.png" alt="" />

4)抽象成員不能私有,如果私有子類沒有辦法訪問

我們可以在抽象類中定義私有成員,但是沒有意義。因?yàn)樽宇惛驹L問不到這些私有成員,而抽象類本身也不能實(shí)例化,所以私有成員訪問不到。

5)子類必須重寫父類的抽象方法

在上面代碼的基礎(chǔ)上,我們定義一個(gè)Student類,繼承抽象類,但是不實(shí)現(xiàn)抽象類的抽象方法,編譯報(bào)錯(cuò)。代碼如下:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.5.png" alt="" />

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é)果如下:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.6.png" alt="" />

抽象類思維導(dǎo)圖總結(jié)如下:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.7.png" alt="" />

抽象方法

1)抽象方法必須定義在抽象類中,

 class Student : Person
    {
        public abstract void Swiming();

        public override void Run()
        {
            base.Say();
            Console.WriteLine("我是學(xué)生,繼承了父類,我可以跑!");
        }
    }

代碼編譯會(huì)報(bào)錯(cuò),如下圖:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.8.png" alt="" />

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é)如下:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.9.png" alt="" />

那么什么時(shí)候使用抽象類呢?

①子類必須重寫父類的方法(相當(dāng)于定義了一個(gè)標(biāo)準(zhǔn),規(guī)范)

②父類沒有必要實(shí)例化,就用抽象類

③抽象類是為了繼承,為了多態(tài)

最后來看一個(gè)示例代碼:

定義一個(gè)抽象類,其中包含抽象方法Run()

 abstract class Person
    {//Run的抽象方法,只要是繼承我的子類都要實(shí)現(xiàn)這個(gè)方法
        public abstract void Run();
    }

分別定義兩個(gè)子類,繼承抽象類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),我們編寫一個(gè)方法如下:

 //該方法變現(xiàn)了多態(tài),根據(jù)需要返回子類的對(duì)象
        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í)例化父類對(duì)象,只是聲明一個(gè)父類對(duì)象的變量來接收方法的返回值
            Person p = GetEntity(Console.ReadLine());
            p.Run();

            Console.ReadLine();
        }

運(yùn)行,分別輸入"工人"和"學(xué)生"的打印結(jié)果如下:

http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/images/7.10.png" alt="" />

到這里這一部分的內(nèi)容就結(jié)束了,希望大家多多提寶貴的意見。