参考:
接口:
- https://www.runoob.com/csharp/csharp-interface.html
- https://www.cnblogs.com/ben-zhang/archive/2012/12/18/2823455.html
- 文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/tour-of-csharp/interfaces
一. 接口和抽象类的区别
抽象类与接口对比:
- 相同点:
- 不能实例化
- 实现接口的任何类或结构都必须实现其所有成员。派生自抽象类的非抽象类,必须包含全部已继承的抽象方法和访问器的实际实现。
- 抽象方法和接口都没有方法主体
- 不同点:
- 接口是一种行为规范。
- 类可以实现无限个接口,但只能继承一个类。一个接口可从一个或多个基接口继承。
- 接口不包含方法的实现。抽象类可以。
- 接口可以包含事件(不能有委托)、索引器、方法和属性。抽象类还能有字段。
还有一点,我们在VS中实现接口时会发现有2个选项,一个是实现接口,一个是显示实现接口。实现接口就是我们平常理解的实现接口,而显示实现接口的话,实现的方法是属于接口的,而不是属于实现类的。
二. 一个可以实例化接口的特例
class Program
{
static void Main(string[] args)
{
//C#中COM接口是可以实例化的,但其实这种写法是使接口“映射”到某一个类上,实际上创建的是这个类的实例。
IWorker worker = new IWorker();
}
}
[ComImport, CoClass(typeof(James1))]
[Guid("d60908eb-fd5a-4d3c-9392-8646fcd1edce")]
public interface IWorker{ void work(string s); }
//ComImport特性发生在tlbimp.exe导入COM类型类库的时候,生成的托管类型会标记有ComImport特性
//Guid特性是一个GUID标识,COM类型是用GUID来标识的。
利用 .NET Reflector 查看时可以很明显的看到 Main 方法里面的代码是:
IWorker worker=new James1();

三. 接口隐式与显示实现
- 隐式接口:
interface IAnimal
{
void Dog();
}
class Animal:IAnimal
{
public void Dog()
{
Console.WriteLine("dog...");
}
}
一般我们都会这么调用:
- 通过类调用:
Animal animal = new Animal();
animal.Dog();
- 或者通过接口调用
IAnimal animal = new Animal();
animal.Dog();
- 显示接口
interface IAnimal
{
void Dog();
}
class Animal:IAnimal
{
void IAnimal.Dog() //注意
{
Console.WriteLine("dog...");
}
}
- 只能通过接口调用
IAnimal animal = new Animal();
animal.Dog();
- 或者进行一下强制类型转换。
Animal animal = new Animal();
(animal as IAnimal).Dog();
总结:
- 当类实现一个接口时,通常使用隐式接口实现,这样可以方便的访问接口方法和类自身具有的方法和属性。
- 当类实现多个接口时,并且接口中包含相同的方法签名,此时使用显式接口实现。即使没有相同的方法签名,仍推荐使用显式接口,因为可以标识出哪个方法属于哪个接口。
- 隐式接口实现,类和接口都可访问接口中方法。显式接口实现,只能通过接口访问
网友评论