第七章 接口
2017-09-21 09:57
183 查看
为什么使用接口?什么情况下使用接口?来看看下面这个例子:
目前有许多文件的压缩格式,包括:.zip、.rar、.cab、.tar等等。假如每种压缩格式都创建一个类,那么每个压缩实现都会有不同的方法签名,无法提供标准的调用规范。虽然方法可以在基类声明,并在子类实现,但是这样会用掉唯一的基类机会(C#只支持单继承)。而且不同的压缩没有通用的代码,这也使得基类变的没有意义。
所以,在这种情况下,不是共享一个基类,而是共享一个接口。基类一般声明子类需要的共享资源,而接口做某一类功能声明。
注意:基类允许共享签名,也允许共享实现,而接口只共享签名,不共享实现。
1、定义接口
接口中不包含实现部分,只包含声明部分。接口中不能声明字段,只能是方法,或属性,而属性不能有实现部分。
接口所有的成员都是公有的,C#不允许为接口成员使用访问修饰符。
一旦类声明实现接口,则该类必须实现接口的所有成员。抽象类允许提供接口成员的抽象实现。
接口不能被实例化,不能通过new创建接口。只有实例化实现接口的类型,才能使用接口的实例。
接口的重要目的是多态性,所以接口的成员不能包括静态成员。
当显式实现该接口的成员时,实现的成员不能通过类实例访问,只能通过接口实例访问。
当隐式实现该接口的成员时,实现的成员可以通过类实例访问,也可以通过接口实例访问,但实现的接口必须为公有的。
interface IFileCompression
{
void Compress(string targetFileName, string[] fileName);
void Uncompress(string compressedFileName, string expandDirectoryName);
}
2、接口的实现
2.1 显式实现接口成员
2.1.1 显式接口声明
显式接口方法的声明,需要在实现接口方法时,使用接口方法的完全限定名,即“接口名.方法”。
interface IPut()
{
void PutName();
}
class A : IPut()
{
public void IPut.PutName()
{
... ...
}
}
2.1.2 显式接口调用
调用显式接口的方法只能通过接口本身调用,所以,必须将实例转换为接口,或将实现接口的类的实例赋值给接口实例,然后再调用显式接口方法。
A a = new A();
((IPut)a).PutName();
2.2
2、接口实现多态性
接口是实现多态的一种重要的手段。实现同一接口的不同类,可以将实例赋值给接口的实例,当使用接口实例调用接口声明的方法时,则根据不同的类实例,调用不同的实现。
interface IPut()
{
void PutName();
}
class A : IPut()
{
public void PutName()
{
System.Console.WriteLine("A类");
}
}
class B : IPut()
{
public void PutName()
{
System.Console.WriteLine("B类");
}
}
void main()
{
IPut ip = new A();
ip.PutName();
ip = new B();
ip.PutName();
}
上例中,类A和类B都继承并实现了接口IPut。在main函数中,首先声明了IPut的实例,该实例指向了类A的实例,此时通过IPut实例调用的PutName()方法,是类A的PutName()方法。再使IPut实例指向类B的实例,此时再通过IPut实例调用的PutName()方法,是类B的PutName()方法。从而实现了多态,即通过一个签名调用不同的实现。
目前有许多文件的压缩格式,包括:.zip、.rar、.cab、.tar等等。假如每种压缩格式都创建一个类,那么每个压缩实现都会有不同的方法签名,无法提供标准的调用规范。虽然方法可以在基类声明,并在子类实现,但是这样会用掉唯一的基类机会(C#只支持单继承)。而且不同的压缩没有通用的代码,这也使得基类变的没有意义。
所以,在这种情况下,不是共享一个基类,而是共享一个接口。基类一般声明子类需要的共享资源,而接口做某一类功能声明。
注意:基类允许共享签名,也允许共享实现,而接口只共享签名,不共享实现。
1、定义接口
接口中不包含实现部分,只包含声明部分。接口中不能声明字段,只能是方法,或属性,而属性不能有实现部分。
接口所有的成员都是公有的,C#不允许为接口成员使用访问修饰符。
一旦类声明实现接口,则该类必须实现接口的所有成员。抽象类允许提供接口成员的抽象实现。
接口不能被实例化,不能通过new创建接口。只有实例化实现接口的类型,才能使用接口的实例。
接口的重要目的是多态性,所以接口的成员不能包括静态成员。
当显式实现该接口的成员时,实现的成员不能通过类实例访问,只能通过接口实例访问。
当隐式实现该接口的成员时,实现的成员可以通过类实例访问,也可以通过接口实例访问,但实现的接口必须为公有的。
interface IFileCompression
{
void Compress(string targetFileName, string[] fileName);
void Uncompress(string compressedFileName, string expandDirectoryName);
}
2、接口的实现
2.1 显式实现接口成员
2.1.1 显式接口声明
显式接口方法的声明,需要在实现接口方法时,使用接口方法的完全限定名,即“接口名.方法”。
interface IPut()
{
void PutName();
}
class A : IPut()
{
public void IPut.PutName()
{
... ...
}
}
2.1.2 显式接口调用
调用显式接口的方法只能通过接口本身调用,所以,必须将实例转换为接口,或将实现接口的类的实例赋值给接口实例,然后再调用显式接口方法。
A a = new A();
((IPut)a).PutName();
2.2
2、接口实现多态性
接口是实现多态的一种重要的手段。实现同一接口的不同类,可以将实例赋值给接口的实例,当使用接口实例调用接口声明的方法时,则根据不同的类实例,调用不同的实现。
interface IPut()
{
void PutName();
}
class A : IPut()
{
public void PutName()
{
System.Console.WriteLine("A类");
}
}
class B : IPut()
{
public void PutName()
{
System.Console.WriteLine("B类");
}
}
void main()
{
IPut ip = new A();
ip.PutName();
ip = new B();
ip.PutName();
}
上例中,类A和类B都继承并实现了接口IPut。在main函数中,首先声明了IPut的实例,该实例指向了类A的实例,此时通过IPut实例调用的PutName()方法,是类A的PutName()方法。再使IPut实例指向类B的实例,此时再通过IPut实例调用的PutName()方法,是类B的PutName()方法。从而实现了多态,即通过一个签名调用不同的实现。
相关文章推荐
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page267
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page273
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page279
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page284
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page302
- 第七章抽象类和接口
- 第七章 容器(本章主要内容)(1个图片,1个类(Collections),3个知识点,6个接口)
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page261
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page268
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page274
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page303
- 第七章抽象类和接口 二、
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page254
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page269
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page297
- 第七章抽象类和接口 三、
- 第七章 接口自动化之本接口文档
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page255
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page262
- Head First C# 中文版 图文皆译 第七章 接口和抽象类 page275