接口
接口的标准化是一个产业强盛的标志。在C#中,面向接口的编程思想是.NET中重要的思想之一,接口是组建设计的灵魂,接口是一种引用类型,在.NET类型系统中,类和结构都可以实现接口,一个类可以实现多个接口,接口之间也可以实现多继承,即 一个接口可以有多个父接口。接口不是实体类型,不可以实例化,只是类型的行为合同规范。接口是面向组件设计与开发的灵魂。是现代软件开发的一个重要的设计手段。其实编程领域的很多思想都是从传统行业借鉴而来的,接口亦是如此。
首先我们来认识一下接口,
public interface IPrint
{
void Print();
void Process();
int Number
{
get;
set;
}
}
上面我们定义了一个接口,包含两个方法签名和一个属性,注意, 接口里面不能包含字段,更加不能包含实现,接口的成员默认都是公开的,不能再加public 修饰符,更不能加其他的,接口不仅可以包含方法和属性,还可以包含索引器(少见)和事件,从本质上来将,这些的东西都是方法,因此有人说接口里面只允许包含方法也不无道理。我们可以通过ildasm工具来查看它的IL代码,我们会发现,接口其实是一个抽象类,且接口的成员只包含方法。
下面我们来看看接口的实现:
using System;
public interface IPrint
{
void Print();
void Process(string name);
int Number
{
get;
set;
}
}
public class Point:IPrint
{
private int _number;
public Point(int number)
{
this._number=number;
}
public int Number //实现接口成员
{
set {_number=value;}
get{return _number;}
}
public void Print() //实现接口成员
{
Console.WriteLine("HelloWorld!");
}
public void Process(string name) //实现接口成员
{
Console.WriteLine("Hello"+name);
}
}
class Test
{
public static void Main()
{
Point p=new Point(1);
p.Print();
p.Process("guowenhui");
Console.WriteLine(p.Number);
}
}
关于接口的实现,继承了某一接口的类必须实现接口中的所有成员,还要实现该接口从其他接口中继承的所有方法。
接口与抽象类的比较(转)
首先说说什么是抽象类,抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。抽象类不能实例化,必须通过继承由派生类实现其抽象方法,因此对抽象类不能使用new关键字,也不能被密封。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。另外,实现抽象方法由override方法来实现。
相同点:
1.都不能被直接实例化,都可以通过继承实现其抽象方法。
2.都是面向抽象编程的技术基础,实现了诸多的设计模式。
不同点:
1.接口支持多继承;抽象类不能实现多继承。
2.接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员。
3.接口是一组行为规范;抽象类是一个不完全的类,着重族的概念。
4.接口可以用于支持回调;抽象类不能实现回调,因为继承不支持。
5.接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。
6.接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。例如,Struct就可以继承接口,而不能继承类。
规则与场合
- 请记住,面向对象思想的一个最重要的原则就是:面向接口编程。
- 借助接口和抽象类,23个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:面向抽象编程。
- 抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
- 接口着重于CAN-DO关系类型,而抽象类则偏重于IS-A式的关系;
- 接口多定义对象的行为;抽象类多定义对象的属性;
- 接口定义可以使用public、protected、internal 和private修饰符,但是几乎所有的接口都定义为public,原因就不必多说了。
- “接口不变”,是应该考虑的重要因素。所以,在由接口增加扩展时,应该增加新的接口,而不能更改现有接口。
- 尽量将接口设计成功能单一的功能块,以.NET Framework为例,IDisposable、IDisposable、IComparable、IEquatable、IEnumerable等都只包含一个公共方法。
- 接口名称前面的大写字母“I”是一个约定,正如字段名以下划线开头一样,请坚持这些原则。
- 在接口中,所有的方法都默认为public。
- 如果预计会出现版本问题,可以创建“抽象类”。例如,创建了狗(Dog)、鸡(Chicken)和鸭(Duck),那么应该考虑抽象出动物(Animal)来应对以后可能出现风马牛的事情。而向接口中添加新成员则会强制要求修改所有派生类,并重新编译,所以版本式的问题最好以抽象类来实现。
- 从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
- 对抽象类不能使用new关键字,也不能被密封,原因是抽象类不能被实例化。
- 在抽象方法声明中不能使用 static 或 virtual 修饰符。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架