当前位置:首页 > 技术 > 正文内容

C# 接口核心机制与多态编程实践

访客 技术 2026年6月21日 1

在C#的面向对象设计中,类仅支持单重继承。为了突破这一限制并实现多重行为契约,接口(Interface)应运而生。一个类可以同时实现多个接口,且接口之间也支持继承关系。

接口的核心特性与规则

接口主要用于定义类或结构体必须实现的功能契约。在成员定义上,接口具有以下关键特性:

  • 允许定义方法、属性、事件和索引器,以及这些成员的任意组合。
  • 支持定义静态方法,但静态方法必须提供具体的实现代码。
  • 支持为成员提供默认实现(Default Interface Methods)。
  • 严禁声明实例级别的数据成员,例如字段、自动实现的属性或类似属性的事件。
  • 接口命名规范通常以大写字母 I 开头。在传统的接口定义中,成员默认是公共的,不允许使用 publicprivateprotectedinternal 等访问修饰符。

接口的基础定义与实现

使用 interface 关键字可以声明接口。以下示例展示了一个泛型数据匹配接口的定义及其在具体类中的显式实现:

public interface IDataMatchable<T>
{
    bool IsMatch(T target);
}

public class Product : IDataMatchable<Product>
{
    public string Sku { get; set; }
    public string Category { get; set; }
    public decimal Price { get; set; }

    // 显式实现接口方法
    bool IDataMatchable<Product>.IsMatch(Product target)
    {
        if (target == null) return false;
        return this.Sku == target.Sku && 
               this.Category == target.Category && 
               this.Price == target.Price;
    }
}

接口的实例化与调用

接口本身无法直接实例化,必须通过实现该接口的类或结构体来创建对象,随后可以将对象引用转换为接口类型进行调用:

Product itemA = new Product { Sku = "A001", Category = "Electronics", Price = 99.99m };
Product itemB = new Product { Sku = "A001", Category = "Electronics", Price = 99.99m };

// 将具体对象赋值给接口引用
IDataMatchable<Product> matcher = itemA;

if (matcher.IsMatch(itemB))
{
    // 通过接口调用自定义的匹配逻辑,而非 Object 基类的默认 Equals
    Console.WriteLine("产品数据完全匹配。");
}
else
{
    Console.WriteLine("产品数据存在差异。");
}

利用接口实现多态机制

接口是实现多态的重要工具。通过让不同的类实现相同的接口,可以在运行时统一处理不同类型的对象。以下示例展示了交通工具接口及其在不同车辆类中的多态实现:

public interface ITransportable<T> : IDataMatchable<T>
{
    void Transport();
}

public class Truck : ITransportable<Truck>
{
    public string LicensePlate { get; set; }
    
    public void Transport()
    {
        Console.WriteLine("卡车正在公路上运输货物。");
    }

    bool IDataMatchable<Truck>.IsMatch(Truck target)
    {
        return this.LicensePlate == target?.LicensePlate;
    }
}

public class Bicycle : ITransportable<Bicycle>
{
    public int GearCount { get; set; }

    public void Transport()
    {
        Console.WriteLine("自行车正在非机动车道上骑行。");
    }

    public bool IsMatch(Bicycle target)
    {
        return this.GearCount == target?.GearCount;
    }
}

多态调用示例

在多态场景下,我们可以使用接口引用来调用具体实现类的方法,从而屏蔽底层类型的差异:

ITransportable<Truck> heavyVehicle = new Truck { LicensePlate = "京A88888" };
heavyVehicle.Transport();

ITransportable<Bicycle> lightVehicle = new Bicycle { GearCount = 21 };
lightVehicle.Transport();
标签: C#

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。