ZetCode

C# 接口

最后修改于 2023 年 7 月 5 日

在本文中,我们将介绍在 C# 中使用接口。

接口定义了一个约定,该约定必须由扩展该接口的类和结构实现。

遥控器是观看者和电视之间的接口。它是该电子设备的接口。遥控器的用户不必了解特定遥控器实际如何工作;他们只需要了解接口:红色或绿色按钮做什么,以及箭头按钮的功能是什么。

另一个常见的接口类比是交通规则。这是驾驶员、自行车手和行人必须遵守的规则。

接口是

对象通过它们公开的方法与外部世界交互。实际的实现对于程序员来说并不重要,或者它也可能是秘密的。一家公司可能会销售一个库,但它不想公开实际的实现。程序员可能会在 GUI 工具包的窗口上调用 Maximize 方法,但不知道该方法是如何实现的。从这个角度来看,接口是对象与外部世界交互的方式,而无需过多地暴露其内部工作原理。

从第二个角度来看,接口是约定。如果达成一致,就必须遵守。它们用于设计应用程序的架构。它们有助于组织代码。

接口是完全抽象的类型。它们使用 interface 关键字声明。接口只能有方法、属性、事件或索引器的签名。所有接口成员都隐式地具有公共访问权限。接口成员不能指定访问修饰符。接口不能有完全实现的方法,也不能有成员字段。一个 C# 类可以实现任意数量的接口。一个接口也可以扩展任意数量的接口。实现接口的类必须实现接口的所有方法签名。

接口用于模拟多重继承。一个 C# 类只能从一个类继承,但它可以实现多个接口。使用接口的多重继承不是关于继承方法和变量。而是关于继承思想或约定,这些思想或约定由接口描述。

接口和抽象类之间存在一个重要的区别。抽象类为继承层次结构中相关的类提供部分实现。另一方面,接口可以由彼此不相关的类实现。

例如,我们有两个按钮。一个经典的按钮和一个圆形的按钮。两者都继承自一个抽象按钮类,该类为所有按钮提供一些公共功能。实现类是相关的,因为它们都是按钮。另一个例子可能有 DatabaseSignIn 类。它们彼此不相关。我们可以应用一个 ILoggable 接口,这将强制它们创建一个方法来进行日志记录。

C# 简单接口

以下程序使用一个简单的接口。

Program.cs
namespace SimpleInterface;

interface IInfo
{
    void DoInform();
}

class Some : IInfo
{
    public void DoInform()
    {
        Console.WriteLine("This is Some Class");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var some = new Some();
        some.DoInform();
    }
}

这是一个简单的 C# 程序,演示了一个接口。

interface IInfo
{
    void DoInform();
}

这是一个接口 IInfo。它具有 DoInform 方法签名。

class Some : IInfo

我们实现了 IInfo 接口。要实现特定的接口,我们使用冒号 (:) 运算符。

public void DoInform()
{
    Console.WriteLine("This is Some Class");
}

该类为 DoInform 方法提供了一个实现。

C# 多接口

下一个示例展示了一个类如何实现多个接口。

Program.cs
namespace MultipleInterfaces;

interface Device
{
    void SwitchOn();
    void SwitchOff();
}

interface Volume
{
    void VolumeUp();
    void VolumeDown();
}

interface Pluggable
{
    void PlugIn();
    void PlugOff();
}

class CellPhone : Device, Volume, Pluggable
{
    public void SwitchOn()
    {
        Console.WriteLine("Switching on");
    }

    public void SwitchOff()
    {
        Console.WriteLine("Switching on");
    }

    public void VolumeUp()
    {
        Console.WriteLine("Volume up");
    }

    public void VolumeDown()
    {
        Console.WriteLine("Volume down");
    }

    public void PlugIn()
    {
        Console.WriteLine("Plugging In");
    }

    public void PlugOff()
    {
        Console.WriteLine("Plugging Off");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var cellPhone = new CellPhone();

        cellPhone.SwitchOn();
        cellPhone.VolumeUp();
        cellPhone.PlugIn();
    }
}

我们有一个 CellPhone 类,它继承自三个接口。

class CellPhone : Device, Volume, Pluggable

该类实现了所有三个接口,这些接口用逗号分隔。CellPhone 类必须实现所有三个接口的所有方法签名。

$ dotnet run
Switching on
Volume up
Plugging In

C# 多接口继承

下一个示例展示了接口如何从多个其他接口继承。

Program.cs
namespace InterfaceInheritance;

interface IInfo
{
    void DoInform();
}

interface IVersion
{
    void GetVersion();
}

interface ILog : IInfo, IVersion
{
    void DoLog();
}

class DBConnect : ILog
{

    public void DoInform()
    {
        Console.WriteLine("This is DBConnect class");
    }

    public void GetVersion()
    {
        Console.WriteLine("Version 1.02");
    }

    public void DoLog()
    {
        Console.WriteLine("Logging");
    }

    public void Connect()
    {
        Console.WriteLine("Connecting to the database");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var db = new DBConnect();

        db.DoInform();
        db.GetVersion();
        db.DoLog();
        db.Connect();
    }
}

我们定义了三个接口。我们可以将接口组织在一个层次结构中。

interface ILog : IInfo, IVersion

ILog 接口继承自另外两个接口。

public void DoInform()
{
    Console.WriteLine("This is DBConnect class");
}

DBConnect 类实现了 DoInform 方法。该方法由 ILog 接口继承,该类实现了该接口。

$ dotnet run
This is DBConnect class
Version 1.02
Logging
Connecting to the database

来源

接口 - 为多种类型定义行为

在本文中,我们介绍了 C# 接口。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经撰写了 1400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 C# 教程