C# 第五章『面向对象』◆第8节:接口

        一、接口的声明

        接口是指定一组函数成员而不实现它们的引用类型。所以只能类和结构来实现接口。接口提出了一种规范,让使用接口的程序的必须严格遵守接口提出的约定。使用interface关键字进行定义,可由方法、属性、事件、索引器或这四种成员类型的任何组合构成。

        接口声明的格式:

修饰符 interface 接口名称
{
    接口内容;
}

        备注:接口名称习惯以I开头,跟在I后的第一个字符也是大写,结尾一般以able结尾。

        接口的特性:

  1. 接口中只能声明方法不能定义,也就是说声明的方法不能有方法体。
  2. 接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型,不能包含虚拟或静态成员。由于不能有字段,所以属性经常被写做自动属性。
  3. 接口可以有访问修饰符,但是接口成员不能包含任何访问修饰符。因为接口中的方法是用来定义对象之间通信的契约,所以指定接口中的方法为私有或保护没有意义。它们默认是公有方法
  4. 接口自身可从多个接口继承,类和结构可继承多个接口,但接口不能继承类。
  5. 接口可以继承其他接口,类可以通过其继承的基类(或接口)多次继承同一个基类。
  6. 接口类似于抽象基类,继承接口的任何类型都必须实现接口的所有成员。
  7. 接口中不能包括构造函数,因此不能直接实例化接口。
  8. 接口可以包含属性、方法、索引器和事件。
  9. 接口中只能定义成员,不能实现成员。
//简单接口的示例1~
using System;

namespace _20220807_1
{
    interface IIfc1
    {
        void PrintOut(string s);
    }
    class Myclass : IIfc1
    {
        public void PrintOut(string s)
        {
            Console.WriteLine($"调用:{s}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Myclass mc = new Myclass();
            mc.PrintOut("object");
        }
    }
}

         二、接口的实现

        实现接口的方式有两种:

        1、当隐式实现该接口的方法时,既可以接口调用方法,也可以用具体类调用方法,但是实现的成员必须是公有的。

//简单接口的示例2~
using System;
namespace Project11
{
    interface IPro
    {
        void Write();
    }
    class Myclass : IPro
    {
        //这里直接写方法,无需IPro.Write()
        public void Write()//这里Write方法必须使用public继续修饰。
        {
            Console.WriteLine("隐式实现接口的方法");
        }
    }
    class Program
    { 
        static void Main(string[] args)
        {
            //实现的方法可以通过声明接口实例访问
            IPro p1 = new Myclass();
            p1.Write();

            //也可以通过类实例化访问
            Myclass p2 = new Myclass(); 
            p2.Write();

        }
    }
}

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

        继承接口后,用户需要实现接口的方法,并且方法名必须与接口定义的方法名一致。IProgram p1 = new MyClass();//声明一个接口实例,但不是对接口进行实例化。

using System;
namespace Project12
{
    interface IProgram
    {
        void Write();
    }
    class MyClass : IProgram
    {
        //实现接口的方法,不能用public,并且必须显式指定接口名称这里是:接口名称.方法
        void IProgram.Write()//这里
        {
            Console.WriteLine("显式实现接口的方法");
        }
    }
    class Program
    { 
        static void Main(string[] args)
        {
            IProgram p1 = new MyClass();//声明一个接口实例,但不是对接口进行实例化。
            p1.Write();
            //MyClass p2 = new MyClass();
        }
    }
}

        3、使用的优缺点

        一般情况下,当类或结构要实现的是单个接口,可以使用隐式实现。如果类或结构继承了多个接口且接口中具有相同名称成员时,就要用到显式实现

        由于显式接口成员属于接口的成员,而不是类的成员,所以不能使用类对象直接访问,只能通过接口对象来访问。

using System;
namespace _20220807_2
{
    interface ImyInterface1
    {
        int add();
    }
    interface ImyInterface2
    {
        int add();
    }
    class myClass : ImyInterface1, ImyInterface2
    {
        int ImyInterface1.add() //显式接口的成员实现
        {
            int a = 9;
            int b = 62;
            return a + b;
        }
        int ImyInterface2.add() //显式接口的成员实现
        {
            int a = 41;
            int b = 65;
            int c = 101;
            return a + b + c;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            myClass mc1 = new myClass();//实例化继承类的对象,该类继承了接口

            ImyInterface1 imy1 = mc1; //使用继承接口类的对象 实例化接口
            Console.WriteLine(imy1.add());//使用接口对象调用接口中的方法

            ImyInterface2 imy2 = mc1; //使用继承接口类的对象实例化接口
            Console.WriteLine(imy2.add());//使用接口调用方法
        }
    }
}

        三、接口的继承

        接口继承和类继承不同。首先,类继承不仅是说明继承,同时也是实现继承;而接口继承只是说明继承,即派生类可以继承基类的方法实现,而派生的接口只继承了父接口的成员方法说明,而没有继承父接口的实现,其次,C#中继承只允许单继承,但是接口继承允许多继承,一个子接口可以有多个父接口。

        接口可以从零或多个接口中继承。从多个接口中继承时,用冒号“:”后跟被继承的接口名字,多个接口名之间用逗号“,”分隔。

        接口的多重继承:在使用多重继承时,要继承的接口之间用逗号“,”分隔。

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();
        }
    }
}

        如果一个接口继承其它接口,那么实现类或结构就需要实现所有接口的成员。

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();
        }
        public void FirstMethod()
        {
            Console.WriteLine("这里是第一个接口的方法");
        }
        public void SecondMethod()
        {
            Console.WriteLine("这里是第二个接口的方法");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45336030/article/details/126202430