C# 学习笔记(5)—— 接口

2023-10-20 18:48:26 浏览数 (1)

什么是接口

接口可以理解为对一组方法声明进行统一的命名,这些方法没有提供任何实现。也就是说,把一组方法声明在一个接口中,然后继承于该接口的类都需要实现这些方法

通过接口,你可以对方法进行统一的管理,避免了在每种类型中重复定义这些方法

如何使用接口来编程

我们学会了面向对象编程,还需要学会面向接口编程

接口的定义

代码语言:javascript复制
interface ICustomCompare
{
    int CompareTo(object other);
}

接口中定义方法不能添加任何访问修饰符,因为接口中的方法默认为 public,如果显示地指定修饰符,则会出现编译时错误

在接口中除了可以定义方法外,还可以包含属性、事件、索引器,或者这四类成员类型的任意组合,也就是说接口类型不能包含字段、运算符重载、实力构造函数和析构函数

继承接口

定义完接口之后,如果有类想继承该接口,则必须实现接口中定义的所有方法

代码语言:javascript复制
interface ICustomCompare
{
    int CompareTo(object other);
}

class Person : ICustomCompare
{
    public int age { get; set; }
    public int CompareTo(object other)
    {
        if (other == null)
        {
            return 1;
        }

        Person p = (Person)other;
        if (this.age < p.age)
        {
            return -1;
        }
        else if (this.age > p.age)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

调用接口中的方法

创建两个待比较对象,然后调用CompareTo方法进行比较

代码语言:javascript复制
static void Main(string[] args)
{
    var p1 = new Person();
    p1.age = 20;
    var p2 = new Person();
    p2.age = 21;
    Console.WriteLine(p1.CompareTo(p2));
    Console.ReadKey();
}

显示接口实现方式

当多个接口中包含相同方法名称、相同返回类型和相同参数时,如果一个类同时实现了这些接口,隐式的接口实现就会出现命名冲突的问题

代码语言:javascript复制
interface IChineseGreeting
{
    void SayHello();
}

interface IAmericanGreeting
{
    void SayHello();
}

class Speaker : IChineseGreeting, IAmericanGreeting
{
    public void SayHello()
    {
        Console.WriteLine("你好");
    }
}

若采用隐式接口实现方式,下面代码将调用相同的SayHello方法,而不管具体获取了哪个接口

为了解决这个问题,我们可以用显示接口实现

代码语言:javascript复制
interface IChineseGreeting
{
    void SayHello();
}

interface IAmericanGreeting
{
    void SayHello();
}

public class Speaker : IChineseGreeting, IAmericanGreeting
{
    void IChineseGreeting.SayHello()
    {
        Console.WriteLine("你好");
    }

    void IAmericanGreeting.SayHello()
    {
        Console.WriteLine("Hello");
    }
}
class Program
{
    static void Main(string[] args)
    {
        var p1 = new Speaker();
        IChineseGreeting chineseGreeting = (IChineseGreeting)p1;
        chineseGreeting.SayHello();
        IAmericanGreeting americanGreeting = (IAmericanGreeting)p1;
        americanGreeting.SayHello();
        Console.ReadKey();
    }
}

在使用显示接口实现方式,需要注意几个问题:

  • 若显示实现接口,方法不能使用任何访问修饰符,显示实现的成员都默认为私有
  • 显示实现的成员默认是私有的,所以这些成员不能通过类的对象进行访问

此时,正确的访问方式应该是把 Speaker 对象显示地转为对应接口,通过接口来调用方法

那么,我们分析了隐式和显示接口实现的两种情况,我们需要区别两种实现和使用场景,明确什么情况下使用哪种方式

  • 采用隐式接口实现时,类和接口都可以访问接口中的方法;若采用显示接口实现方式,接口方法只能通过接口来访问,因此此时接口方法默认为私有
  • 当类实现单个接口时,通常使用隐式接口实现方式,这样类的对象可以直接去访问接口方法
  • 当类实现多个接口时,并且接口中包含相同的方法名称、参数和返回类型时,则应使用显示接口实现方式。即使没有相同的方法前面时,在实现多个接口是,仍推荐使用显示的方式,因为这样可以标识出哪个方法属于哪个接口

接口与抽象类

接口和抽象类有时候会一起使用,共同服务于面向对象编程

归纳总结

这里主要介绍了接口的定义、实现以及其方法的调用;分析了隐式接口与显示接口实现的区别

0 人点赞