【C#】——接口

  • 了解接口的基本概念
  • 掌握接口的声明及使用
  • 掌握接口的多重继承的实现
  • 熟悉显式接口成员的实现方法

    由于C#中的类不支持多重继承,但是客观世界出现多重继承的情况又比较多,因此为了避免传统多重继承给程序带来的复杂性等问题,同时保证多重继承给程序员的诸多好处,提出了接口概念。

    通过接口可以实现多重继承的功能。

一、接口的概念及声明

1.接口是一种用来定义程序的协议,它描述可属于任何类或结构的一组相关行为。

接口可由方法、属性、时间和索引器或这4种成员类型的任何组合构成,但不能包含字段。

2.类和结构可以像类继承基类或结构一样从接口继承,而且可以继承多个接口。

当类或结构继承接口时,它继承成员定义但不继承实现。

若要实现接口成员,类中的对应成员必须是公共的、非静态的,并且与接口成员具有相同的名称和签名。类的属性和索引器可以为接口上定义的属性或索引器定义额外的访问器。

例如,接口可以声明一个有 get 访问器的属性,而实现该接口的类可以声明同时带有 get 和 set 访问器的同一属性。但是,如果属性或索引器使用显式实现,则访问器必须匹配。

3.接口可以继承其他接口,类可以通过其继承的基类或即可欧多次继承某个接口。在这种情况下,如果将该接口声明为新类的一部分,则类只能实现该接口一次。如果没有将继承的接口声明为新类的一部分,其实现将由声明它的基类提供。基类可以使用虚拟成员实现接口成员。在这种情况下,继承几口的类可通过重写虚拟成员来更改接口行为。

说明:接口可以包含方法、属性、索引器和事件作为成员,但是并不能设置这些成员的具体值。也就是说,只能定义,不能给它里面定义的东西赋值。

  1. 接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
  2. 不能直接实例化接口。
  3. 接口可以包含事件、索引器、方法和属性。
  4. 接口不包含方法的实现。
  5. 类和结构可从多个接口继承。
  6. 接口自身可从多个接口继承。

C#中声明接口时,使用 interface 关键字,其语法格式如下:

修饰符 interface 接口名称:继承接口列表

{

        接口内容;

}

a.    声明接口时,除 interface 关键字和接口名称外,其他的都是可选项。

b.    可以使用 new 、public 、protected 、internal  和 private 等修饰符声明接口,但接口成员必须是公共的。

【例1】下面的代码声明了一个接口,该接口中包含编号和姓名两个属性,还包含一个自定义方法 ShowInfo,该方法用来显示定义的编号和属性。

interface IMyInterface
    {
        string ID       //编号(可读可写)
        {
            get;
            set;
        }
        string Name     //姓名(可读可写)
        {
            get;
            set;
        }
        void ShowInfo();    //显示定义的编号和姓名
        {
            Console.WriteLine("编号\t 姓名");
            Console.WriteLine(ID+"\t"+Name);
        }
    }

二、接口的实现与继承

接口通过类继承来实现,一个类虽然只能继承一个基类,但可以继承任意接口。声明实现接口的类时,需要在基类类表中包含类所实现的接口的名称。

【例2】创建一个控制台应用程序,该程序在【例1】的基础上实现,Program 类继承自接口 IMyInterface ,并实现了该接口中的所有属性和方法。然后在 Main 方法中实例化 Program 类的一个对象,并使用该对象实例化  IMyInterface 接口。最后通过实例化的接口对象访问派生类中的属性和方法。

class Program : IMyInterface        //继承自接口
    {
        string id = "";
        string name = "";
        public string ID                //编号
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
            }
        }
        public string Name              //姓名
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public void ShowInfo()          //显示定义的编号和姓名
        {
            Console.WriteLine("编号\t 姓名");
            Console.WriteLine(ID + "\t" + Name);
        }
        static void Main(string[] args)
        {
            Program program = new Program();    //实例化Prograam类对象
            IMyInterface imyinterface = program;//使用派生类对象实例化接口IMyInterface
            imyinterface.ID = "TM";             //为派生类中的ID属性赋值
            imyinterface.Name = "C#";           //为派生类中的Name属性赋值
            imyinterface.ShowInfo();            //调用派生类中的方法显示定义的属性值
        }
    }

上面的实例中只继承了一个接口,接口还可以多重继承,使用多重继承时,要继承的接口之间用逗号( ,)分隔。

【例3】创建一个控制台应用程序,其中声明 3 个接口 IPeople、ITeacher 和 IStudent,其中,ITeacher 和 IStudent 继承自

IPeople。然后使用Program 类继承这 3 个接口,并分别实现这 3 个接口中的属性和方法。

interface IPeople
    {
        string Name
        {
            get;
            set;
        }
        string Sex
        {
            get;
            set;
        }

    }
    interface ITeacher : IPeople
    {
        void Teach();
    } 
    interface IStudent : IPeople
    {
        void Study();
    }
    class Program : IPeople, ITeacher, IStudent
    {
        string name = "";
        string sex = "";
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }
        public string Sex
        {
            get
            {
                return sex;
            }
            set
            {
                sex = value;
            }
        }
        public void Teach()
        {
            Console.WriteLine(Name + "" + Sex + "教师");
        }
        public void Study()
        {
            Console.WriteLine(Name + "" + Sex + "学生");
        }
        static void Main(string[] args)
        {
            Program program = new Program();
            ITeacher iteacher = program;
            iteacher.Name = "TM";
            iteacher.Sex = "男";
            iteacher.Teach();
            IStudent istudent = program;
            istudent.Name = "C#";
            istudent.Sex = "男";
            istudent.Study();
        }
    }

三、显式接口成员实现

    如果类实现两个接口,并且这两个接口包含具有相同签名的成员,那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。然而,如果两个接口成员实现不同的功能,则可能会导致其中一个接口的实现不正确或两个接口的实现都不正确,这时可以显式地实现接口成员,即创建一个仅通过该接口调用并特定于该接口的类成员。显式接口成员实现是使用接口名称和一个句点命名该类成员来实现的。

【例4】创建一个控制台应用程序,其中声明了两个接口 ImyInterface1 和 ImyInterface2 ,在这两个接口中声明一个同名方法 Add。然后定义一个类 MyClass ,该类继承自己经声明的两个接口。在 MyClass 类中实现接口中的方法时,由于 ImyInterface1 和ImyInterface2 接口中声明的方法名相同,这里使用了显式接口成员实现。最后在主程序类 Program 的 Main 方法中使用接口对象调用接口中定义的方法。

interface IMyInterface1
    {
        int Add();
    }
    interface IMyInterface2
    {
        int Add();
    }
    class myClass : IMyInterface1, IMyInterface2
    {
        ///求和方法
        int IMyInterface1.Add()
        {
            int x = 3;
            int y = 5;
            return x + y;
        }
        ///求和方法
        int IMyInterface2.Add()
        {
            int x = 3;
            int y = 5;
            int z = 7;
            return x + y + z;
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            myClass myclass = new myClass();
            IMyInterface1 imyinterface1 = myclass;
            Console.WriteLine(imyinterface1.Add());
            IMyInterface2 imyinterface2 = myclass;
            Console.WriteLine(imyinterface2.Add());
        }
    }

1.显式接口成员实现中不能包含访问修饰符 abstract、virtual、override 或 static 修饰符。

2.显式接口成员属于接口成员,而不是类的成员,因此,不能使用类对象直接访问,只能通过接口对象来访问。

猜你喜欢

转载自blog.csdn.net/cangsheng45/article/details/79781533