文末有“实战代码”
接口表示一种能力
A.做这项工作需要一个钳工(木匠/程序员)
钳工是一种“能力”,不关心具体是谁
B.接口是一种能力
体现在接口的方法上
C.面向接口编程
程序设计时
1.关心实现类有何能力,而不关心实现细节
2.面向接口的约定而不考虑接口的具体实现
如何理解接口是一种能力?
接口有比抽象类更好的特性:
1.可以被多继承
2.设计和实现完全分离
3.更自然的使用多态
4.更容易搭建程序框架
5.更容易更换实现
生活中,我们使用的两相电源插座,规定了:
--两个接头间的额定电压
--两个接头间的距离
--接头的形状
接口是一种约定
体现在接口名称和注释上
--体现在接口名称和注释上
--方法的实现方式要通过注释来约定
面向接口编程
程序设计时面向接口的约定而不考虑具体实现
举例说明【防盗门】
--门有“开”和“关”的功能,锁有“上锁”和“开锁”的功能
--将门定义为抽象类,锁定义为接口
--防盗门继承门,实现锁的接口
[ 分析 ]
--防盗门是一个门
--防盗门有一个锁,上锁和开锁是“能力”
就像电脑的USB接口
我们使用它插U盘,给手机充电和传输数据,插鼠标,插风扇;
电脑只是提供了一个接口,不提供鼠标功能、手机功能、风扇功能;
但是鼠标、手机、风扇可以根据电脑接口的“约束(规范)”后,实现接口以外的其他功能!
接口是一种能力,但是接口也是一个标准(规范)
认识一下接口
所有方法都是:public
public interface MyInterface {
public void foo();
//其他方法
}
接口注意的几点
1.接口方法不能用public abstract等修饰。接口内不能有字段变量,构造函数。
2.接口内可以定义属性(有get和set的方法)。如string color { get ; set ; }这种。
3.实现接口时,必须和接口的格式一致。
4.必须实现接口的所有方法。
接口的特点
接口的定义是指定一组函数成员而不实现成员的引用类型,其它类型和接口可以继承接口。定义还是很好理解的,但是没有反映特点,接口主要有以下特点:
(1)通过接口可以实现多重继承,C# 接口的成员不能有 public、protected、internal、private 等修饰符。原因很简单,接口里面的方法都需要由外面接口实现去实现方法体,那么其修饰符必然是 public。C# 接口中的成员默认是 public 的,java 中是可以加 public 的。
(2)接口成员不能有 new、static、abstract、override、virtual 修饰符。有一点要注意,当一个接口实现一个接口,这2个接口中有相同的方法时,可用 new 关键字隐藏父接口中的方法。
(3)接口中只包含成员的签名,接口没有构造函数,所有不能直接使用 new 对接口进行实例化。接口中只能包含方法、属性、事件和索引的组合。接口一旦被实现,实现类必须实现接口中的所有成员,除非实现类本身是抽象类。
(4)C# 是单继承,接口是解决 C# 里面类可以同时继承多个基类的问题。
接口和抽象类的区别
接口用于规范,抽象类用于共性。抽象类是类,所以只能被单继承,但是接口却可以一次实现多个。
接口中只能声明方法,属性,事件,索引器。而抽象类中可以有方法的实现,也可以定义非静态的类变量。
抽象类可以提供某些方法的部分实现,接口不可以。抽象类的实例是它的子类给出的。接口的实例是实现接口的类给出的。
在抽象类中加入一个方法,那么它的子类就同时有了这个方法。而在接口中加入新的方法,那么实现它的类就要重新编写(这就是为什么说接口是一个类的规范了)。
接口成员被定义为公共的,但抽象类的成员也可以是私有的、受保护的、内部的或受保护的内部成员(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。
此外接口不能包含字段、构造函数、析构函数、静态成员或常量。
还有一点,我们在VS中实现接口时会发现有2个选项,一个是实现接口,一个是显示实现接口。实现接口就是我们平常理解的实现接口,而显示实现接口的话,实现的方法是属于接口的,而不是属于实现类的。
必须知道的接口特性
1.接口不可以被实例化
2.实现类必须实现接口的所有方法
3.实现类可以实现多个接口
4.接口中的变量都是静态常量
C#中的接口
声明接口
[修饰符] interface 接口名{
属性定义
方法定义
}
多接口继承
[修饰符] interface 接口名 : 父接口1,父接口2, …… {
属性定义
方法定义
}
类使用接口
class 类名 : 父类名,接口1,接口2, …… {
}
总结
1.一个类可以实现多个接口,非抽象类实现接口时必须实现接口中的全部方法
2.抽象类利于代码复用,接口利于代码维护
3.C#中接口
3-1.成员主要是方法、属性
3-2.不能包含常量、变量、构造方法和任何静态成员
3-3.不能显式指定任何修饰符
阅读代码,找出错误
public interface MyInterface {
public MyInterface(); × 语法错误没有返回类型
public void method1();√
public void method2(){ } ×不含方法体没有;符号
private void method3();× 不能私有
void method4();√
int method5();√
int TYPE = 1;√
}
实战代码
门是一个抽象类
///
/// 门抽象父类
///
public abstract class Door//抽象父类还是类
{
///
/// 开门
///
public abstract void Open();
///
/// 关门
///
public abstract void Close();
}
厨房门
厨房门继承抽象门
public class CookDoor : Door
{
public override void Close()
{
Console.WriteLine("关闭厨房门");
}
public override void Open()
{
Console.WriteLine("推开厨房门");
}
}
防盗门
防盗门继承了抽象类门,
锁和门铃是门扩展,所以把锁和门铃定义成接口,并且继承。
///
/// 防盗门(接口是多实现的) 如果既有父类,又有接口
///
public class TheftproofDoor : Door,ILock,IMusic
{
public override void Close()
{
Console.WriteLine("关闭防盗门");
}
public override void Open()
{
Console.WriteLine("推开防盗门");
}
public void OpenLock()
{
Console.WriteLine("开锁");
}
public void UpLock()
{
Console.WriteLine("上锁");
}
public void PlayerMusic()
{
//winform组件,直接调用 .wav
Console.WriteLine("正在播放~忘情水");
}
}
锁
锁接口类里面写锁的能力,锁的能力是:1.上锁,2.开锁
///
/// 密码锁(接口,抽象的)能力
///
public interface ILock
{
///
/// 上锁
///
void UpLock();//public公共的
///
/// 开锁
///
void OpenLock();
}
门铃
门铃接口类里面写门铃的能力,门铃的能力是:响起音乐
///
/// 门铃
///
public interface IMusic
{
void PlayerMusic();
}