C#中的接口

一、什么是接口

  1. 含义:接口是指定一组函数成员而不实现它们的引用类型。(只能用类和结构实现接口)
  2. 接口可以包含实例方法、属性、事件、索引器或这四种成员类型的任意组合。
  3. 接口可以包含静态构造函数(不能创建接口的实例)、字段、常量或运算符

C#中的接口_第1张图片

 二、声明接口

  1. 按照惯例接口名称应该以大写的“I”开头。
  2. 接口声明可以有任何的访问修饰符(public、protected、internal、private)。
  3. 根据需求,在接口中声明没有方法体的函数成员(方法体使用分号代替)。
  4. 接口的成员是隐式public,不允许private访问修饰符

C#中的接口_第2张图片

 三、实现接口

  1. 只有类和结构才能实现接口。
  2. 实现方法:在基类列表中包含接口名,为接口的每一个成员提供实现。

C#中的接口_第3张图片

  • 抽象类和普通类实现接口有所不同,抽象类可以选择不实现接口中的方法。

C#中的接口_第4张图片

C#中的接口_第5张图片 C#中的接口_第6张图片

 四、接口是引用类型

  1. 接口是引用类型,如果一个类实现了接口,我们可以通过强制转换,把类对象引用强制转换成接口引用。
  2. 除了强转运算符,我们以可以通过as运算符将对象引用转换为接口引用。
    //接口
    interface IIfc1 
    {
        void PrintOut(string s);
    }

    //未实现IIfc1接口的类
    class MyClass : IIfc1
    {
        public void PrintOut(string s)
        {
            Console.WriteLine("调用者:{0}",s);
        }
    }

    //未实现IIfc1接口的类
    class MyClass1 { }

    //测试
    internal class Program
    {
        static void Main(string[] args)
        {
            //例1:可以使用强转运算符将类对象引用转换为接口引用
            MyClass mc = new MyClass();
            mc.PrintOut("MyClass对象");//调用者:MyClass对象

            IIfc1 ifc1 = (IIfc1)mc;
            ifc1.PrintOut("IIfc1接口");//调用者:IIfc1接口

            //例2:使用as运算符将类对象引用转换为接口引用
            //好处:避免将类对象引用转换接口引用失败而抛异常
            //如果类实现了接口,表达式返回指向接口的引用
            //如果类没有实现接口,表达式返回null而不是抛出异常
            MyClass1 myClass1 = new MyClass1();
            IIfc1 ifc = myClass1 as IIfc1;
            if (ifc != null)
                Console.WriteLine("转换成功,IIfc1接口");
            else
                Console.WriteLine("转换失败,类对象未实现该接口!");

        }
    }

理解图如下: C#中的接口_第7张图片

 五、实现多个接口

类只能单继承,接口可以多实现。实现的多个接口在基类列表中以逗号分隔。

C#中的接口_第8张图片

 1.实现具有重复成员的接口

如果一个类实现了多个接口,并且其中一些接口有相同签名和返回类型的成员,那么类可以实现单个成员来满足所有包含重复成员的接口。

    interface IIfc1 { void PrintOut(string s); }
    interface IIfc2 { void PrintOut(string s); }

    class MyClass : IIfc1, IIfc2
    {
        public void PrintOut(string s)
        {
            Console.WriteLine(s);
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            myClass.PrintOut("一个实现方法实现多个相同返回类型及签名的接口");
        }
    }

C#中的接口_第9张图片
2.多个接口的引用

如果类实现了多个接口,我们可以获取每一个接口的独立引用。

    interface IIfc1 { void PrintOut(string s); }
    interface IIfc2 { void PrintOut(string s); }

    class MyClass : IIfc1, IIfc2
    {
        public void PrintOut(string s)
        {
            Console.WriteLine(s);
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            myClass.PrintOut("一个实现方法实现多个相同返回类型及签名的接口");

            IIfc1 ifc1 = (IIfc1)myClass;
            IIfc2 ifc2 = (IIfc2)myClass;

            ifc1.PrintOut("接口1");
            ifc2.PrintOut("接口2");
        }
    }

C#中的接口_第10张图片

3.显式接口成员实现

  1. 我们可以使用限定接口名称显式地为每一个接口分别进行实现。
  2. 实现类中的显示接口成员实现只可以通过指向接口的引用来访问。

C#中的接口_第11张图片 

    interface IIfc1 { void PrintOut(string s); }
    interface IIfc2 { void PrintOut(string s); }

    class MyClass : IIfc1, IIfc2
    {
        void IIfc1.PrintOut(string s)
        {
            Console.WriteLine("IIfc1:{0}",s);
        }

        void IIfc2.PrintOut(string s)
        {
            Console.WriteLine("IIfc2:{0}", s);
        }

        public void Method() 
        {
            PrintOut("光头强");//编译报错
            this.PrintOut("熊大");//编译报错

            ((IIfc1)this).PrintOut("熊二");//显式接口成员实现只可以通过指向接口的引用来访问
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();//创建类对象
            
            IIfc1 ifc1 = (IIfc1)myClass;//获取IIfc1的引用
            ifc1.PrintOut("接口1");

            IIfc2 ifc2 = (IIfc2)myClass;//获取IIfc2的引用
            ifc2.PrintOut("接口2");

        }
    }

C#中的接口_第12张图片

六、派生成员作为实现

实现接口的类可以从它的基类继承实现的代码。

    interface IIfc1 { void PrintOut(string s); }

    class MyBaseClass 
    { 
        public void PrintOut(string s) 
        {
            Console.WriteLine(s);
        }
    }

    class Derived : MyBaseClass,IIfc1
    {
        //Derived中是空的
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            Derived derived = new Derived();

            IIfc1 ifc1 = derived as IIfc1;//转换为指向IIfc1的引用

            if (ifc1 != null)
                ifc1.PrintOut("从接口的引用调用PrintOut,这个方法被Derived的基类MyBaseClass实现");
        }
    }

C#中的接口_第13张图片 

七、接口可以多继承

  1. 接口可以从一个或多个接口继承。
  2. 结果接口包含它继承的所有接口和所有基接口的成员。

C#中的接口_第14张图片
八、不同的类实现一个接口

综合练习:

    //接口
    interface ILiveBirth 
    {
        string BabyCalled();
    }
    
    //动物类
    class Animal { }

    //狗狗
    class Dog : Animal, ILiveBirth
    {
        public string BabyCalled()
        {
            return "puppy";
        }
    }

    //猫猫
    class Cat : Animal, ILiveBirth
    {
        public string BabyCalled()
        {
            return "Kitten";
        }
    }
    
    //鸟
    class Bird : Animal { }

    //测试
    internal class Program
    {
        static void Main(string[] args)
        {
            Animal[] animals = new Animal[3];
            
            animals[0] = new Bird();
            animals[1] = new Cat();
            animals[2] = new Dog();

            foreach (Animal animal in animals) 
            {
                ILiveBirth? lb = animal as ILiveBirth;
                if (lb != null)
                    Console.WriteLine("BabyCalled:{0}", lb.BabyCalled());
            }
        }
    }

 九、总结

  1. 接口是指定一组函数成员而不实现它们的引用类型。
  2. 接口只能被类和结构实现。
  3. 接口中可以包含实例方法、属性、事件、索引器、字段、常量和运算符。
  4. 接口的成员是隐式public,不允许private访问修饰符。
  5. 接口可以继承多个接口。
  6. 抽象类可以选择实现接口中的方法,普通类必须实现接口中的方法。
  7. 接口不能创建对象,实现接口的类对象引用可以转换为接口引用。
  8. 实现类中的显示接口成员实现只可以通过指向接口的引用来访问。
  9. 实现接口的类可以从它的基类继承实现的代码。

(注:本章学习总结自《C#图解教程》)

你可能感兴趣的:(C#基础笔记,c#,开发语言,visual,studio)