在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

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

解析接口

這一篇主要來解析關(guān)于面向?qū)ο笾凶羁傄囊粋€概念——接口。

對于接口來說,C#是有規(guī)定使用Interface關(guān)鍵字來聲明接口。它的聲明是和類一致的??梢哉f接口就是一個特殊的抽象類。如下代碼:

class Program
    {
        static void Main(string[] args)
        {
        }
    }

    //聲明一個可以飛的接口
    interface IRunable
    {
        //包含可以被繼承的子類實現(xiàn)的方法
        void Run();
    }

由以前的抽象類的知識可以知道,抽象類是沒有辦法實例化的(因為含有抽象成員,而抽象成員不含有方法體)。那么接口可不可以實例化呢?答案是肯定的,不能實例化。看下面的一段代碼:

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

這個時候編譯器告訴我們無法創(chuàng)建抽象類或者接口的實例。

二,接口可以定義哪些成員

1)接口就是一個定義"具有某種能力的抽象類",既然接口是類,那么它的內(nèi)部可以定義哪些成員呢?

首先,在普通的類中,可以有字段,屬性,方法,索引器,抽象方法等等。那么接口呢?

看下面直接聲明字段,編譯器會報錯,告訴我們接口內(nèi)不能聲明字段

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

既然接口內(nèi)不能有字段,那也就不存在封裝字段了。所以上邊圖示的封裝字段的代碼也是錯誤的。

同理由上面的代碼也可以知道,在接口中是不可以定義顯式的屬性(因為在屬性中要操作字段賦值,但是字段沒有辦法在接口中聲明)。

那么接口可以聲明自動屬性么?看下面的代碼:

 //聲明一個可以飛的接口
    interface IRunable
    {
        //聲明字段
        int nAge { get; set; }

        string strName { get; set; }
        ////包含可以被繼承的子類實現(xiàn)的方法
        void Run();

    }

代碼可以順利編譯通過,那么是為什么呢?這就要看.NET的源碼,我把源碼編譯后的比較結(jié)果如下圖:

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

抽象方法就不用多了,本來接口就是一個抽象愛類,當然可以定義抽象類,但是不在使用abstract關(guān)鍵字,而且方法必須沒有方法體;

2)繼承接口的子類必須實現(xiàn)接口的所有抽象成員。

我們先來看下面的代碼:

 //聲明一個接口,其中包含屬性和未實現(xiàn)方法void
    interface IRunable
    {
        string strName { get; set; }
        void Run();
    }

下面來一個實現(xiàn)類,如下:

 class Person:IRunable
    {
       public  void Run()
        {
            Console.WriteLine("我可以奔跑!");
        }
    }

這時候,我們編譯,編譯器會告訴我們什么呢?如下圖:

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

所以繼承接口的類,必須實現(xiàn)接口的所有抽象成員。

正確的代碼如下:

 class Person:IRunable
    {
       public  void Run()
        {
            Console.WriteLine("我可以奔跑!");
        }

       public string strName
       {
           get
           {
               return strName;
           }
           set
           {
               strName = value;
           }
       }
    }

通過以上的代碼可以發(fā)現(xiàn):

①我們的繼承類在實現(xiàn)接口成員的時候不需要使用override關(guān)鍵字

②實現(xiàn)接口的時候,必須保持簽名一致

由前面抽象類的知識我們有沒有這樣的疑問,什么時候使用抽象類,什么時候使用接口呢?

總結(jié)如下:

①使用抽象類:可以找到父類,并且希望通過父類繼承給子類一些成員

②使用接口:接口就是一個純粹的為了規(guī)范實現(xiàn)的類。比如:多個類具有相同的方法,但是卻找不到父類,就可以將方法定義在接口中。讓這些類去實現(xiàn)。

下面糾紛別來看兩端代碼,比較抽象類和接口的異同,首先是抽象類:

class Program
    {
        static void Main(string[] args)
        {
            Student s = new Student();
            //Student類通過繼承獲得NAge屬性
            s.NAge = 10;
            s.Eat();

            Console.WriteLine("--------Student和Worker類分別通過繼承獲得了父類的非私有成員,實現(xiàn)了父類的抽象方法--------");

            Worker w = new Worker();
            //Worker類通過繼承獲得NAge屬性
            w.NAge = 40;
            w.Eat();

            Console.ReadKey();
        }
    }

    //定義父類
    abstract class Person
    {
       private int nAge;

        public int NAge
        {
            get { return nAge; }
            set { nAge = value; }
        }

        private void Run()
        {
            Console.WriteLine("我是父類,我可以跑!");
        }
        public abstract void Eat();

    }

    class Student : Person
    {
        //子類覆寫了父類的抽象方法
        public override void Eat()
        {
            Console.WriteLine("我是子類,我繼承了父類,我可以在學校吃飯!");
        }
    }

    class Worker:Person
    {
        //同樣Worker也通過繼承獲得了父類的非私有成員
        public override void Eat()
        {
            Console.WriteLine("我是子類,我繼承父類,我可以在工廠吃飯");
        }
    }

接下來,來看看接口是怎么規(guī)范多個類的實現(xiàn)的。

class Program
    {
        static void Main(string[] args)
        {
            Student s = new Student();
            s.strName = "小學生";
            s.Run();
            Console.WriteLine(s.strName);
            Console.WriteLine("--------------------");
            Worker w = new Worker();
            w.strName = "看我能不能瀆職";
            w.Run();
            Console.WriteLine(w.strName);

            Console.ReadKey();
        }
    }

    interface IRunable
    {
        //規(guī)范子類必須實現(xiàn)strName屬性
        string strName { get; set; }
        //規(guī)范子類必須實現(xiàn)Run()方法
        void Run();

    }

    class Student:IRunable
    {
        //這里是子類的字段
        string strname;
        public string strName
        {
            get
            {
                return strname;
            }
            set
            {
                strname = value;
            }
        }

        public void Run()
        {
            Console.WriteLine("我是小學生,我在學校里面跑步!");
        }

    }

    class Worker:IRunable
    {
        string strname;
        public string strName
        {
            get
            {
                return "工人";
            }
            set
            {
                strname = value;
            }
        }

        public void Run()
        {
            Console.WriteLine(  "我是工人,我需要在廠區(qū)跑!");
        }
    }

由以上的代碼可不可以發(fā)現(xiàn),接口僅僅在規(guī)定一個規(guī)范子類的實現(xiàn),而抽象類可以通過繼承,繼承給子類某些成員。

最后來看一下,接口的顯示實現(xiàn),我先看接口的普通實現(xiàn)(以上的代碼實現(xiàn)接口的方式都是隱式實現(xiàn))

interface IRunable
    {
        //規(guī)范子類必須實現(xiàn)strName屬性
        string strName { get; set; }
        //規(guī)范子類必須實現(xiàn)Run()方法
        void Run();

    }

    class Student:IRunable
    {
        //這里是子類的字段
        string strname;
        public string strName
        {
            get
            {
                return strname;
            }
            set
            {
                strname = value;
            }
        }

        public void Run()
        {
            Console.WriteLine("我是小學生,我在學校里面跑步!");
        }

    }

顯式實現(xiàn)接口

 class Student:IRunable
    {
        //這里是子類的字段
        string strname;
        //顯示實現(xiàn)接口
        string IRunable.strName
        {
            get
            {
                return strname;
            }
            set
            {
                strname = value;
            }
        }

        void IRunable.Run()
        {
            Console.WriteLine("我是小學生,我在學校里面跑步!");
        }

    }

顯示的實現(xiàn)接口是為了解決方法名沖突的問題。但是顯示實現(xiàn)接口會出現(xiàn),在上面的代碼中會出現(xiàn)一個問題,如下圖:

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

為什么會這樣呢?

因為顯式實現(xiàn)接口的方法是私有的,不能通過對象變量來調(diào)用。那應(yīng)該怎么調(diào)用呢,看下面的代碼:

class Program
    {
        static void Main(string[] args)
        {

            //里氏替換原則,父類變量指向子類對象,并通過父類變量調(diào)用子類方法
            IRunable ir = new Student();
            ir.Run();
            Console.ReadKey();
        }
    }

    interface IRunable
    {
        //規(guī)范子類必須實現(xiàn)strName屬性
        string strName { get; set; }
        //規(guī)范子類必須實現(xiàn)Run()方法
        void Run();

    }

    class Student:IRunable
    {
        //這里是子類的字段
        string strname;
        //顯示實現(xiàn)接口
        string IRunable.strName
        {
            get
            {
                return strname;
            }
            set
            {
                strname = value;
            }
        }

        void IRunable.Run()
        {
            Console.WriteLine("我是小學生,我在學校里面跑步!");
        }

       // Student s = new Student();

    }

打印結(jié)果如下:

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

顯式實現(xiàn)接口,這個接口的方法,只能通過接口變量來調(diào)用。

接口導圖總結(jié)如下:

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

上一篇:繼承