文章目录

  • 接口
  • 接口的声明
  • 接口的实现
  • 接口的继承


接口

接口描述的是可属于任何类或结构的一组相关功能,所以实现接口的类或结构必须实现接口定义中指定的接口成员。接口使用interface关键字进行定义,可由方法、属性、事件、索引器或这四种成员类型的任意组合构成。

接口的声明

接口的声明格式:
修饰符 interface 接口名称
{
//成员;
}
使用接口时,需要注意以下几点:
(1) 接口中只能声明方法不能定义,也就是说声明的方法不能有方法体。
(2) 接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型、不能包含静态成员。由于不能有字段,所以属性经常被写作自动属性。
(3) 接口成员都是自动公开的,且不能包含任何访问修饰符。因为接口中的方法用来定义对象之间通信的契约,所以指定接口中的方法为私有或保护没有意义。它们默认为公有方法。
(4) 接口自身可从多个接口继承,类和结构可继承多个接口,但接口不能继承类。

接口的实现

接口类似于抽象基类,不能直接实例化接口;接口中的方法都是抽象方法,实现接口的任何非抽象类型都必须实现接口的所有成员。
实现接口的方式有以下两种:
(1) 当隐式实现该接口的方法时,既可以用接口调用方法,也可以用具体类调用方法,但是实现的成员必须是公有的。
编写程序,隐式实现接口的方法。

using System;
namespace Project12
{
    interface IProgram
    {
        void Write();
    }
    class Program : IProgram
    {
        public void Write()
        {
         Console.WriteLine("隐式实现接口的方法");
        }
        static void Main(string[] args)
        {
            IProgram p = new Program();   //也可以通过接口实例访问
            p.Write();
            Program pro = new Program();  //实现的成员可以通过类实例访问
            pro.Write();
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了隐式实现接口的方法。在代码中,Write方法必须使用public进行修饰。实现的成员可以通过类的实例化访问,也可以通过接口实例访问。

隐式实现接口的方法
隐式实现接口的方法

(2) 当显式实现该接口的方法时,不能使用访问修饰符public,并且必须显式指定接口名称。实现的接口成员不能通过类的实例访问,只能通过接口的实例访问。
编写程序,显式实现接口的方法。

using System;
namespace Project11
{
    interface IProgram
    {
        void Write();
    }
    class Program : IProgram
    {        
        void IProgram.Write()//显式实现接口成员
        {
            Console.WriteLine("显式实现接口的方法");
        }
        static void Main(string[] args)
        {
            Console.WriteLine("实例化类的对象调用接口方法:");
            Program pro = new Program();  
            IProgram p1 = pro;         //使用派生类对象实例化接口
            p1.Write();
            Console.WriteLine("声明接口实例调用接口方法:");
            IProgram p2 = new Program(); //声明一个接口实例,但不是对接口进行实例化
            p2.Write();
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了显式实现接口的方法。在代码中,Program类实现了IProgram接口,接口的实现与类的继承语法格式类似:“class Program : IProgram”。继承接口后,用户需要实现接口的方法Write,并且方法名必须与接口定义的方法名一致。最后需要注意,在调用Write方法时,是声明一个接口实例,而不是对接口进行实例化

实例化类的对象调用接口方法:
显式实现接口的方法
声明接口实例调用接口方法:
显式实现接口的方法

接口可以显式实现和隐式实现,那么这两种实现到底有什么优缺点呢?一般情况,当类或者结构要实现的是单个接口,可以使用隐式实现。如果类或者结构继承了多个接口并且接口中具有相同名称的成员时,就要用到显式实现。
编写程序,实现两个接口中同名但是具有不同功能的方法。

using System;
namespace Project13
{
    interface ImyInterface1
    {
        int add();
    }
    interface ImyInterface2
    {
        int add();
    }
    class myClass : ImyInterface1, ImyInterface2
    {
        int ImyInterface1.add() //显式接口的成员实现
        {
            int a = 4;
            int b = 6;
            return a + b;
        }
        int ImyInterface2.add() //显式接口的成员实现
        {
            int a = 4;
            int b = 6;
            int c = 10;
            return a + b + c;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            myClass myclass = new myClass();//实例化继承类的对象,该类继承了接口
            ImyInterface1 imy1 = myclass; //使用继承接口类的对象 实例化接口
            Console.WriteLine(imy1.add());//使用接口对象调用接口中的方法
            ImyInterface2 imy2 = myclass; //使用继承接口类的对象实例化接口
            Console.WriteLine(imy2.add());//使用接口调用方法
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了两个接口拥有同名的方法。在代码中,声明了两个接口ImyInterface1和ImyInterface2,并且在这两个接口中都声明了一个同名的方法add。如果在myclass类通过隐式实现方法时,但是这两个方法的功能不一样,就会导致其中一个接口实现不正确或者两个都不能正确实现,所以需要在类中指定各自的接口名称。由于显式接口成员属于接口的成员,而不是类的成员,所以不能使用类对象myclass直接访问,只能通过接口对象(imy1或imy2)来访问。

10
20

接口的继承

接口继承和类继承不同。首先,类继承不仅是说明继承,同时也是实现继承;而接口继承只是说明继承。也就是说,派生类可以继承基类的方法实现,而派生的接口只继承了父接口的成员方法说明,而没有继承父接口的实现,其次,C#中类继承只允许单继承,但是接口继承允许多继承,一个子接口可以有多个父接口。
接口可以从零或多个接口中继承。从多个接口中继承时,用冒号“:”后跟被继承的接口名字,多个接口名之间用逗号“,”分割。
编写程序,声明三个接口分别为IPeople、ITeacher、IStudent,其中后两者继承于IPeople,然后Program类继承这三个接口,并且实现三个接口中的所有属性和方法。
如果一个接口继承其他接口,那么实现类或结构就需要实现所有接口的成员。

using System;
namespace Project14
{
    interface IPeople
    {
        //由于不能有字段,所以属性经常被写作自动属性
        string Name      //声明Name属性
        {
            get;
            set;
        }
        string Gender   //声明Gender属性
        {
            get;
            set;
        }
    }
    interface ITeacher : IPeople
    {
        void teach();
    }
    interface IStudent : IPeople
    {
        void study();
    }
    class Program : IPeople, ITeacher, IStudent
    {
        string _name = "";
        string _gender = "";
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        public string Gender
        {
            get
            {
                return _gender;
            }
            set
            {
                _gender = value;
            }
        }
        public void teach()
        {
            Console.WriteLine("大家好,我叫{0},我是{1}生,我是一名老师", Name, Gender);
        }
        public void study()
        {
            Console.WriteLine("大家好,我叫{0},我是{1}生,我是一名学生", Name, Gender);
        }
        static void Main(string[] args)
        {
            ITeacher iteach = new Program();
            iteach.Name = "张三";
            iteach.Gender = "男";
            iteach.teach();
            IStudent istu = new Program();
            istu.Name = "李四";
            istu.Gender = "女";
            istu.study();
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了接口的继承。在代码中声明了三个接口,分别为IPeople、ITeacher和IStudent。接着在IPeople接口中声明Name和Gender属性。然后在ITeacher接口中声明Teach方法,在IStudent接口中声明Study方法。再让Program类继承这三个接口,并对所有接口中的方法和属性进行实现。最后在Main方法中,分别声明ITeacher和IStudent接口的实例,并赋值与输出。

大家好,我叫张三,我是男生,我是一名老师
大家好,我叫李四,我是女生,我是一名学生

编写程序,让一个接口继承另一个接口。

using System;
namespace Project15
{
    interface IFirst
    {
        void FirstMethod();
    }
    interface ISecond : IFirst
    {
        void SecondMethod();
    }
    class Program : ISecond
    {
        static void Main()
        {
            Program pro = new Program();    //实例化类的对象
            IFirst first = pro;             //使用派生类对象实例化接口IFirst
            ISecond second = pro;           //使用派生类对象实例化接口ISecond
            first.FirstMethod();
            second.SecondMethod();
            Console.ReadKey();
        }
        public void FirstMethod()
        {
            Console.WriteLine("这里是第一个接口的方法");
        }
        public void SecondMethod()
        {
            Console.WriteLine("这里是第二个接口的方法");
        }
        
    }
}

【程序分析】本例演示了接口继承接口。在代码中声明了两个接口IFirst和ISecond,接着在IFirst接口中声明FirstMethod方法;在ISecond接口中声明SecondMethod方法。然后,让ISecond接口继承于IFirst,再让Program类继承于ISecond。最后,在Main方法中实现这两个接口的方法,并且通过实例化接口,调用接口中的方法。

这里是第一个接口的方法
这里是第二个接口的方法