-
接口(Interface):行为规范
《C#从入门到精通:实例驱动学习指南》
接口(Interface):行为规范
-
接口的核心定义
接口是一种行为契约,它规定了类或结构体必须实现的方法、属性、事件或索vb.net教程C#教程python教程SQL教程access 2010教程
引器的签名(名称、参数、返回值),但不提供任何具体实现。接口的核心价值在于:
统一不同类的行为规范(比如“所有支付方式都必须有Pay方法”);
突破C#单继承的限制,让类同时拥有多种行为;
解耦代码依赖,降低模块间的耦合度。 -
接口的语法规则
接口使用interface关键字定义,其成员具有以下特点:
成员默认是public(无需显式添加public修饰符);
不能包含字段、构造函数、析构函数或静态成员(C#8.0+支持静态成员);
方法/属性仅定义签名,无具体实现(C#8.0+支持默认实现);
接口本身不能实例化,但可作为引用类型指向实现类的对象。
基础语法示例:
csharp
// 定义接口:规范"可支付"行为
public interface IPayable
{
// 方法签名:无实现
void Pay(decimal amount);
// 属性签名:仅定义get/set
string PaymentMethod { get; }
}
3. 实例:支付接口的实现
我们以支付场景为例,定义IPayable接口规范支付行为,再让Alipay、WeChatPay等类实现该接口。
3.1 完整代码实现
csharp
using System;
// 1. 定义接口:规范支付行为
public interface IPayable
{
// 支付方法:必须实现
void Pay(decimal amount);
// 支付方式属性:必须实现
string PaymentMethod { get; }
}
// 2. Alipay类实现IPayable接口
public class Alipay : IPayable
{
// 实现PaymentMethod属性
public string PaymentMethod => "支付宝";
// 实现Pay方法
public void Pay(decimal amount)
{
Console.WriteLine($"[{PaymentMethod}] 支付成功:{amount:C}");
}
}
// 3. WeChatPay类实现IPayable接口
public class WeChatPay : IPayable
{
public string PaymentMethod => "微信支付";
public void Pay(decimal amount)
{
Console.WriteLine($"[{PaymentMethod}] 支付成功:{amount:C}");
}
}
// 4. 测试类:统一调用支付行为
class Program
{
static void Main()
{
// 接口引用指向不同实现类
IPayable alipay = new Alipay();
IPayable wechat = new WeChatPay();
// 统一调用Pay方法(多态特性)
alipay.Pay(199.99m);
wechat.Pay(299.5m);
}
}
3.2 逐行代码讲解
接口定义:IPayable接口规定了两个成员——Pay方法(支付行为)和PaymentMethod属性(支付方式名称),仅定义签名,无实现;
类实现接口:Alipay和WeChatPay类通过: IPayable声明实现接口,必须全部实现接口中的成员(否则编译报错);
属性实现:PaymentMethod属性用Lambda表达式返回固定字符串(简化写法);
方法实现:Pay方法根据自身支付方式输出支付结果;
测试逻辑:用IPayable类型的引用指向不同实现类,调用Pay方法时自动执行对应类的实现(体现多态)。
输出结果:
[支付宝] 支付成功:¥199.99
[微信支付] 支付成功:¥299.50
-
基础知识拓展
4.1 接口的核心特性
多实现:一个类可同时实现多个接口,比如UnionPay类可同时实现IPayable和IRefundable接口;
接口继承:接口可继承其他接口,比如IOnlinePay : IPayable,实现IOnlinePay的类需同时实现两个接口的成员;
接口作为参数:方法可接收接口类型参数,实现对所有接口实现类的统一处理(如ProcessPayment(IPayable payTool));
显式实现:当类实现多个接口且存在同名成员时,需用显式实现区分(见下文示例)。
4.2 接口与抽象类的区别
| 特性 | 接口(Interface) | 抽象类(Abstract Class) |
|---|---|---|
| 继承限制 | 类可实现多个接口 | 类只能继承一个抽象类 |
| 成员类型 | 仅方法/属性/事件/索引器(无字段/构造函数) | 可包含字段、构造函数、虚方法、抽象方法等 |
| 实现方式 | 必须完全实现所有成员(除非用默认实现) | 可部分实现(抽象方法需子类实现) |
| 核心用途 | 规范行为契约(What to do) | 共享代码逻辑(How to do) |
| 实例化 | 不能实例化 | 不能实例化 |
4.3 C#8.0+:接口的默认实现
C#8.0开始支持接口的默认实现,允许接口为成员提供基础实现。当类实现接口时,可选择重写或直接使用默认实现,避免因接口新增成员导致现有代码崩溃。
示例:
csharp
public interface IPayable
{
void Pay(decimal amount);
// 默认实现:退款方法
void Refund(decimal amount)
{
Console.WriteLine($"默认退款流程:退回{amount:C}");
}
}
// Alipay类重写Refund方法
public class Alipay : IPayable
{
public void Pay(decimal amount) => Console.WriteLine($"支付宝支付{amount:C}");
// 重写默认方法
public void Refund(decimal amount)
{
Console.WriteLine($"支付宝退款:退回{amount:C}(1-3个工作日到账)");
}
}
// WeChatPay类使用默认Refund方法
public class WeChatPay : IPayable
{
public void Pay(decimal amount) => Console.WriteLine($"微信支付{amount:C}");
// 未重写Refund,直接使用接口默认实现
}
4.4 显式实现:解决同名成员冲突
当类实现多个接口且存在同名成员时,需用显式实现指定成员属于哪个接口。显式实现的成员默认是private(只能通过接口引用调用)。
示例:
csharp
// 两个接口都有Pay方法
public interface IOnlinePay { void Pay(decimal amount); }
public interface IOfflinePay { void Pay(decimal amount); }
// UnionPay类实现两个接口
public class UnionPay : IOnlinePay, IOfflinePay
{
// 显式实现IOnlinePay的Pay方法
void IOnlinePay.Pay(decimal amount)
{
Console.WriteLine($"银联在线支付:{amount:C}");
}
// 显式实现IOfflinePay的Pay方法
void IOfflinePay.Pay(decimal amount)
{
Console.WriteLine($"银联POS支付:{amount:C}");
}
}
// 调用显式实现的方法
UnionPay up = new UnionPay();
((IOnlinePay)up).Pay(500); // 输出:银联在线支付:¥500.00
((IOfflinePay)up).Pay(300); // 输出:银联POS支付:¥300.00
-
总结
接口是C#中实现行为规范化和多态的核心工具,其核心价值在于:
统一规范:让不同类遵循相同的行为标准;
灵活扩展:突破单继承限制,让类同时拥有多种行为;
解耦代码:降低模块间的依赖,提高代码可维护性。
在实际开发中,接口常用于框架设计(如ASP.NET Core的IRepository)、插件系统(如第三方支付集成)等场景,是编写高质量、可扩展代码的必备技能。
练习:定义IShippable接口规范物流行为(Ship(string orderId)),让Express、Courier类实现该接口,并编写测试代码验证多态调用。
csharp
// 接口定义
public interface IShippable { void Ship(string orderId); }
// Express类实现
public class Express : IShippable
{
public void Ship(string orderId) => Console.WriteLine($"快递发货:订单{orderId}");
}
// 测试代码请自行补充...
本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49369.html
最新更新
抽象类(Abstract Class):部分实现
接口(Interface):行为规范
多态:方法重写与接口多态
继承:代码复用与扩展
封装:访问修饰符与属性(Property)
构造函数与析构函数
类的定义与对象的创建
跳转语句:break、continue与return
循环语句:for、while与foreach
第二十四章:工作流高级逻辑
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比










