C# 接口核心机制与多态编程实践
在C#的面向对象设计中,类仅支持单重继承。为了突破这一限制并实现多重行为契约,接口(Interface)应运而生。一个类可以同时实现多个接口,且接口之间也支持继承关系。
接口的核心特性与规则
接口主要用于定义类或结构体必须实现的功能契约。在成员定义上,接口具有以下关键特性:
- 允许定义方法、属性、事件和索引器,以及这些成员的任意组合。
- 支持定义静态方法,但静态方法必须提供具体的实现代码。
- 支持为成员提供默认实现(Default Interface Methods)。
- 严禁声明实例级别的数据成员,例如字段、自动实现的属性或类似属性的事件。
- 接口命名规范通常以大写字母
I开头。在传统的接口定义中,成员默认是公共的,不允许使用public、private、protected或internal等访问修饰符。
接口的基础定义与实现
使用 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();