# 接口 interface
> 接口可以理解成是一种协议,他规定了类该做什么,而怎么做的部分则是由类来定义的。
>
接下来声明一个接口:
```
interface a//定义接口的关键字和接口名字
{
int Var { get; set; }//定义接口的属性成员
void b(int a);//定义接口的方法成员
}
```
上面的代码用关键字 interface 定义了一个名称为 a 的接口,他有一个类型为 void 名称为 b 的方法,但是方法中并没有代码。
接下来定义一个类,用于支持这个接口:
```
internal class c : a//一个名为c的类,他支持a接口( internal暂时可以忽略,他会在下文中得到解释 )
{
int var;//字段
public int Var { get => var; set => var = value; }//属性
public void b(int a)//实现了该做什么
{
Var = a;
Console.WriteLine($"你好!工程师!{Var}");//规定了怎么做
/* Console.WriteLines 是一个 System程序集 中的方法,用于向控制台出数据,
不必深入了解他,这里把他当成Echo()就好,你甚至可以直接将他替换成Echo()*/
}
}
```
以上的代码定义了一个名为 c 的类,他支持上面声明的 a 接口。接下来讨论一个问题:类c 是如何支持 a接口 的呢?
一个类要支持一个接口就必须要实现接口的所有成员(相同的类型、名称、参数)。
类c 中有一个 b方法 ,他的类型、名称、参数都和 接口a 中的 成员b 一模一样,唯一不同的是 类c 中的 b方法 定义了"怎么做"的代码,所以之前说过接口就像是一个协议,如果类签署了这个协议就必须做到协议中规定的事,和现实中不同的是这个协议只能规定类要做什么,不能规定类要怎么做。
还有一点需要注意的是类可以使用访问修饰符(上面的类中使用了一个 **internal** 关键字,这一般是类的默认访问修饰符,表示类只能被自身所在代码文件中访问到,当你不使用访问修饰符声明类时就默认使用这个访问修饰符,类可以手动指定这个修饰符)
接口也可以使用访问修饰符,他的默认访问修饰符和类相同,但是接口的成员不能使用访问修饰符,他是默认公共( **public**)的,无法修改的,这是因为类继承接口就必须实现接口成员,但是又无法访问接口成员,就会自相矛盾。
一个类可以支持多个接口:
```
interface Iitf1
{
void OutPut1();//接口成员1
}
interface Iitf2
{
void OutPut2();//接口成员2
}
interface Iitf3
{
void OutPut3();//接口成员3
}
```
这里有3个接口,他们都有各自的成员,接下来用一个类支持他们:
```
class myClass : Iitf1, Iitf2, Iitf3
{
public void OutPut1()//方法实现
{
Console.WriteLine("你好!工程师!");
}
public void OutPut2()//方法实现
{
Console.WriteLine("你好!建筑师!");
}
public void OutPut3()//方法实现
{
Console.WriteLine("你好!科学家!");
}
}
```
这个类中实现了这三个接口中的方法,也就可以支持这三个接口。
接口也是可以继承的,并且可以继承多个:
```
interface IitfA
{
void OutPut1();
}
interface IitfB
{
void OutPut2();
}
interface Iitf:IitfA,IitfB
//他继承了IitfA和IitfB
{
void OutPut3();
}
```
Iitf 接口继承了 IitfA 和 IitfB 接口,如果要支持 Iitf 接口就必须实现 IitfA、IitfB、Iitf 三个接口中所有的方法。
还有如果父类中实现了一个接口规定的方法并且可以继承,那继承他的子类就可以支持那个接口,因为他从父类继承了支持接口的方法。
总而言之,只要实现了所继承接口所有的成员,类就可以支持那些接口。
但是接口是不支持字段成员的:
```
interface Iitf
{
int a;
double b;
}
```
这样会报错。到这里总结一下接口的部分特性:
> 1. 接口可以有访问修饰符,但是接口的成员没有。
> 2. 接口的成员只能是不能包含具体代码的方法名称或属性名称。
> 3. 接口可以继承多个接口,而且由于所有接口成员都是公共的,所以他们都会被继承。
> 4. 类可以支持多个接口,但是支持接口就必须实现接口规定的所有方法,可以是直接定义的,也可以是从基类继承过来的,所以只要继承了基类实现接口的方法,子类也可以支持该接口。
>
## **如何使用接口:**
接口除了规定了类该怎么做的条条框框外还可以使用接口来访问类的方法:
```
class Program
{
/*这里的代码调用的是文章开头的代码*/
static void Main(string[] args)
{
c myObj = new c();//实例化
a myIitf = myObj;//将myObj赋值给接口
myIitf.b(5);//通过接口调用方法
myObj.b(5);//通过实例调用方法
Console.ReadKey();
}
}
```
输出结果:
```
你好!工程师!5
你好!工程师!5
```
还可以规定方法只能被接口调用,不过需要修改一下之前的代码
```
void a.b(int a)//方法声明直接调用了接口中的
{
Var = a;
Console.WriteLine($"你好!工程师!{Var}");
}
```
将类 c 中的方法的代码修改成这样,直接通过接口 a 来声明方法,其结果就是只能使用接口来调用这个方法。
/*这里的代码调用的是文章开头的代码*/
```
static void Main(string[] args)
{
c myObj = new c();//实例化
a myIitf = myObj;//将myObj赋值给接口
myIitf.b(5);//通过接口调用方法可行
myObj.b(5);//直接通过类访问代码会报错
Console.ReadKey();
}
```
- 序言
- 写在前面的话
- 太空工程师
- MEA小组
- 一、入门
- 1.1 基础概念
- 1.2 编程工具
- 1.3 变量
- 1.4 函数 Function
- 1.5 基本语法
- 1.5.1 运算符
- 1.5.2 if
- 1.5.3 for
- 1.5.4 其他语法
- 1.3 类 Class
- 二、编程块
- 2.1 方块的概念
- 2.2 List<T>结构
- 2.3 获取方块
- 2.4 方块的使用
- 三、Ship 类
- 3.1 简介
- Ship v0.5
- 代码
- 手册(待更新)
- 例子(待更新)
- Ship v1.0
- 代码
- 例子
- 文档
- 实例化
- 内置变量
- 内置方法
- Target类
- 四、运动控制算法在SE中的应用
- 4.1 运动控制介绍
- 4.2 过程控制
- 4.3 震荡和动态误差
- 4.4 误差累加方案
- 4.5 PID算法
- 4.6 对PID算法的一点点简化
- 4.7 一阶惯性系统的PID算法优化的研究
- 五、MEA方块类
- 5.0 核心代码目录
- v1.0核心代码
- v1.1 核心代码
- v2.0 核心代码
- 5.1 类的概念
- 5.2 MEA的方块类(Block)
- 5.3 方块类文档
- 5.4 方块类2.0 全教程
- 5.4.1 安装和使用
- 5.4.2 方块类(Block)
- 5.4.3 显示屏类(DisplayScreen)
- 5.4.4 LCD类(LCD)
- 5.4.5 主控座椅类(Cockpit)
- 六、疯猴的编程笔记
- 第一个程序
- 获取和控制其他块
- 物流与生产
- 界面与通信
- 运动与姿态
- 侦测与导航
- 七、SteamZhou的笔记
- 有趣而花里胡哨的IDEA
- 八、质子对撞炮的笔记
- 属性 Property
- 接口 interface