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


            一、接口的声明

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

            接口声明的格式:

    1. 修饰符 interface 接口名称
    2. {
    3. 接口内容;
    4. }

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

            接口的特性:

    1. 接口中只能声明方法不能定义,也就是说声明的方法不能有方法体。
    2. 接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型,不能包含虚拟或静态成员。由于不能有字段,所以属性经常被写做自动属性。
    3. 接口可以有访问修饰符,但是接口成员不能包含任何访问修饰符。因为接口中的方法是用来定义对象之间通信的契约,所以指定接口中的方法为私有或保护没有意义。它们默认是公有方法
    4. 接口自身可从多个接口继承,类和结构可继承多个接口,但接口不能继承类。
    5. 接口可以继承其他接口,类可以通过其继承的基类(或接口)多次继承同一个基类。
    6. 接口类似于抽象基类,继承接口的任何类型都必须实现接口的所有成员。
    7. 接口中不能包括构造函数,因此不能直接实例化接口。
    8. 接口可以包含属性、方法、索引器和事件。
    9. 接口中只能定义成员,不能实现成员。
    1. //简单接口的示例1~
    2. using System;
    3. namespace _20220807_1
    4. {
    5. interface IIfc1
    6. {
    7. void PrintOut(string s);
    8. }
    9. class Myclass : IIfc1
    10. {
    11. public void PrintOut(string s)
    12. {
    13. Console.WriteLine($"调用:{s}");
    14. }
    15. }
    16. class Program
    17. {
    18. static void Main(string[] args)
    19. {
    20. Myclass mc = new Myclass();
    21. mc.PrintOut("object");
    22. }
    23. }
    24. }

             二、接口的实现

            实现接口的方式有两种:

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

    1. //简单接口的示例2~
    2. using System;
    3. namespace Project11
    4. {
    5. interface IPro
    6. {
    7. void Write();
    8. }
    9. class Myclass : IPro
    10. {
    11. //这里直接写方法,无需IPro.Write()
    12. public void Write()//这里Write方法必须使用public继续修饰。
    13. {
    14. Console.WriteLine("隐式实现接口的方法");
    15. }
    16. }
    17. class Program
    18. {
    19. static void Main(string[] args)
    20. {
    21. //实现的方法可以通过声明接口实例访问
    22. IPro p1 = new Myclass();
    23. p1.Write();
    24. //也可以通过类实例化访问
    25. Myclass p2 = new Myclass();
    26. p2.Write();
    27. }
    28. }
    29. }

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

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

    1. using System;
    2. namespace Project12
    3. {
    4. interface IProgram
    5. {
    6. void Write();
    7. }
    8. class MyClass : IProgram
    9. {
    10. //实现接口的方法,不能用public,并且必须显式指定接口名称这里是:接口名称.方法
    11. void IProgram.Write()//这里
    12. {
    13. Console.WriteLine("显式实现接口的方法");
    14. }
    15. }
    16. class Program
    17. {
    18. static void Main(string[] args)
    19. {
    20. IProgram p1 = new MyClass();//声明一个接口实例,但不是对接口进行实例化。
    21. p1.Write();
    22. //MyClass p2 = new MyClass();
    23. }
    24. }
    25. }

            3、使用的优缺点

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

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

    1. using System;
    2. namespace _20220807_2
    3. {
    4. interface ImyInterface1
    5. {
    6. int add();
    7. }
    8. interface ImyInterface2
    9. {
    10. int add();
    11. }
    12. class myClass : ImyInterface1, ImyInterface2
    13. {
    14. int ImyInterface1.add() //显式接口的成员实现
    15. {
    16. int a = 9;
    17. int b = 62;
    18. return a + b;
    19. }
    20. int ImyInterface2.add() //显式接口的成员实现
    21. {
    22. int a = 41;
    23. int b = 65;
    24. int c = 101;
    25. return a + b + c;
    26. }
    27. }
    28. class Program
    29. {
    30. static void Main(string[] args)
    31. {
    32. myClass mc1 = new myClass();//实例化继承类的对象,该类继承了接口
    33. ImyInterface1 imy1 = mc1; //使用继承接口类的对象 实例化接口
    34. Console.WriteLine(imy1.add());//使用接口对象调用接口中的方法
    35. ImyInterface2 imy2 = mc1; //使用继承接口类的对象实例化接口
    36. Console.WriteLine(imy2.add());//使用接口调用方法
    37. }
    38. }
    39. }

            三、接口的继承

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

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

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

    1. using System;
    2. namespace Project14
    3. {
    4. interface IPeople
    5. {
    6. //由于不能有字段,所以属性经常被写作自动属性
    7. string Name //声明Name属性
    8. {
    9. get;
    10. set;
    11. }
    12. string Gender //声明Gender属性
    13. {
    14. get;
    15. set;
    16. }
    17. }
    18. interface ITeacher : IPeople
    19. {
    20. void teach();
    21. }
    22. interface IStudent : IPeople
    23. {
    24. void study();
    25. }
    26. class Program : IPeople, ITeacher, IStudent
    27. {
    28. string _name = "";
    29. string _gender = "";
    30. public string Name
    31. {
    32. get
    33. {
    34. return _name;
    35. }
    36. set
    37. {
    38. _name = value;
    39. }
    40. }
    41. public string Gender
    42. {
    43. get
    44. {
    45. return _gender;
    46. }
    47. set
    48. {
    49. _gender = value;
    50. }
    51. }
    52. public void teach()
    53. {
    54. Console.WriteLine("大家好,我叫{0},我是{1}生,我是一名老师", Name, Gender);
    55. }
    56. public void study()
    57. {
    58. Console.WriteLine("大家好,我叫{0},我是{1}生,我是一名学生", Name, Gender);
    59. }
    60. static void Main(string[] args)
    61. {
    62. ITeacher iteach = new Program();
    63. iteach.Name = "张三";
    64. iteach.Gender = "男";
    65. iteach.teach();
    66. IStudent istu = new Program();
    67. istu.Name = "李四";
    68. istu.Gender = "女";
    69. istu.study();
    70. }
    71. }
    72. }

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

    1. using System;
    2. namespace Project15
    3. {
    4. interface IFirst
    5. {
    6. void FirstMethod();
    7. }
    8. interface ISecond : IFirst
    9. {
    10. void SecondMethod();
    11. }
    12. class Program : ISecond
    13. {
    14. static void Main()
    15. {
    16. Program pro = new Program(); //实例化类的对象
    17. IFirst first = pro; //使用派生类对象实例化接口IFirst
    18. ISecond second = pro; //使用派生类对象实例化接口ISecond
    19. first.FirstMethod();
    20. second.SecondMethod();
    21. }
    22. public void FirstMethod()
    23. {
    24. Console.WriteLine("这里是第一个接口的方法");
    25. }
    26. public void SecondMethod()
    27. {
    28. Console.WriteLine("这里是第二个接口的方法");
    29. }
    30. }
    31. }
  • 相关阅读:
    Ansys Speos | 新型计算方法:使用 GPU 提升计算速率
    DTD建模 ,XML(详解)
    AlphaFold2源码解析(4)--模型架构
    PCIe ECAM机制
    测试--自动化测试:关于unittest框架
    docker基本管理
    【MySQL】insert相关SQL语句
    每日汇评:积极的数据可能会推动澳元/美元的上涨
    加拿大公司注册
    SR-LIO--手写紧耦合IESKF
  • 原文地址:https://blog.csdn.net/qq_45336030/article/details/126202430