# 接口学习
## 接口定义
> 接口是一种契约和规范;是指定一组对象的定义而非实现的引用类型;是C#实现多继承的机制;也是多态的一种常用实现方式。
## 接口特点
1. 接口可以包含属性、方法、索引器、委托与事件等对象,但不能包含字段,也不能包含构造或析构函数(对象的创建与销毁,应该在实现类所关心的,接口只关心需要实现的功能约定)
1. 接口中的对象都是公开权限的,否则接口无意义:不能使用范围修饰符(public private internal protected)
1. 不能有 static abstract virtual override sealed 等违反接口意义的修饰符
1. 接口只包含对象的定义,不能包含对象的实现,也不能直接实例化接口
1. 接口的实现类必须实现接口中的所有成员,除非实现类本身是抽象类(通过具体的可执行代码实现接口抽象成员的操作);接口实现子类中,可用new关键字隐藏父接口中的方法。
1. 接口可以多继承,可用来解决C#类的单继承问题
1. 接口名称一般都以“I”作为首字母,以与实现类区分
## 接口的隐式实现与显式实现
+ 接口
``` csharp
///
/// 接口
///
public interface IBase
{
void Print();
}
```
+ 隐式实现
``` csharp
///
/// 隐式实现接口
///
public class Base : IBase
{
//必须有访问修饰符
//对象(方法)名,即是接口对象(方法)名
public void Print()
{
Console.WriteLine($"隐式实现接口方法");
}
}
```
+ 显式实现
``` csharp
///
/// 显式实现接口
///
public class Base : IBase
{
//不允许有访问修饰符
//对象(方法)名为”接口名.对象(方法)名"
void IBase.Print()
{
Console.WriteLine("显式实现接口方法");
}
}
```
+ 语法区别
> 隐式实现必须加 *访问修饰符* 显式实现不能用任何*访问修饰符* ;隐式实现对象名是接口对象名,显式实现,对象名为*接口名.对象名*
+ 调用区别
> 隐式实现,可以由实现类或接口类调用;显式实现只能由接口类调用。
``` csharp
//隐式实现调用
class Program
{
static void Main(string[] args)
{
//接口类可以调用
IBase base = new Base();
base.Print();
//实现类可以调用
Base base2 = new Base();
base2.Print();
}
}
//显式实现调用
class Program
{
static void Main(string[] args)
{
//接口类可以调用
IBase base = new Base();
base.Print();
//实现类不能调用
Base base2 = new Base();
//语法错误,不可调用
base2.Print();
}
}
```
小结:
1. 通常情况下,使用隐式方式实现接口;
2. 需要区分不同接口或者有同名对象时,使用显式实现;
3. 业务需要时,使用显式实现
## 接口继承
## 子类重复实现父类接口
```csharp
///
/// 接口
///
public interface IBase
{
string GetA();
string GetB();
}
///
/// 接口实现基类
///
public class Base : IBase
{
public string GetA()
{
return "基类 GetA方法";
}
public string GetB()
{
return "基类 GetB方法";
}
}
///
/// 接口实现子类
///
public class ChildA:Base,IBase
{
public string GetB()
{
return "实现子类 GetB方法";
}
}
```
## 运行时多态与编译时多态