C#学习(四)之接口

第四周章老师详细讲了C#有关接口,数组以及字符串方面的知识,由于后两者知识点太过零碎,不太容易记录,所以本次学习记录就只讨论一下接口。

接口,使用interface关键字进行声明,功能是把所需成员组合起来,以封装一定功能的集合。它好比一个模板,在其中定义了对象必须实现的成员,通过类或结构来实现它。

需要牢牢记住的是:接口不能直接实例化,接口不能包含成员的任何代码,只定义成员本身。接口成员的具体代码由实现接口的类提供。

接口的声明格式如下列代码所示:

1 [attributes] [access-modifiers] interface interface-name [:base-inteface-list] 
2 { 
3        interface body 
4 }


各项释义

attributes(可选):附加的定义性信息。

access-modifiers(可选):允许使用的修饰符有 new 和四个访问修饰符。分别是:newpublicprotectedinternalprivate。在一个接口定义中同一修饰符不允许出现多次,new 修饰符只能出现在嵌套接口中,表示覆盖了继承而来的同名成员。public, protected, internal, private 修饰符定义了对接口的访问权限,默认值是internal。

interface-name :接口名, 习惯上以大写 I 开头。

base-inteface-list(可选):包含一个或多个显式基接口的列表,接口间由逗号分隔。

interface body 接口主体(不能有访问修饰符),只是定义接口的方法和属性等的签名,实际的实现是写在使用该接口的class里。

实际接口声明代码示例如下:

1 public interface IStorable
2 {
3     void Read( );//注意这里一定不能有public之类的修饰符
4     void Write(object);//并且只是签名,不能有实际内容
5 }

接口的继承使用示例如下:

1 public class Document : IStorable//如继承一般类一般继承接口
2 {
3     public void Read( ) {...}//这里可以加修饰符了,并写出实现代码
4     public void Write(object obj) {...}
5     // ...
6 }

一个类是可以继承多个接口的,代码示例如下:

 1 interface ICompressible//定义新接口
 2 {
 3     void Compress();
 4     void Decompress();
 5 }
6 public class Document : IStorable, ICompressible 7 { 8 //实现IStorable 9 public void Read( ) {...} 10 public void Write(object obj) {...} 11 // 实现ICompressible 12 public void Compress(){ …} 13 public void Decompress() { …} 14 }

另外,接口也是可以继承接口的,代码示例如下:

 1 interface ILoggedCompressible 
 2 : ICompressible
 3 {
 4     void LogSavedBytes();
 5 }
 6 
 7 public class Document : ILoggedCompressible 
 8 {
 9     // 实现ICompressible
10     public void Compress(){ …}
11     public void Decompress() { …}
12     // 实现ILoggedCompressible 
13     public void LogSavedBytes() { …}
14 }

接口继承接口不用实现继承的接口中的方法,不过一个类继承一个有继承其他接口的接口时,一定要实现继承链上所有接口中的所有方法,不然就会报错。

同时,接口也是可以同时继承多个接口的,代码示例如下:

1 interface IStorableCompressible 
2      : IStorable, ILoggedCompressible//同时继承两个接口
3 {
4     void LogOriginalSize();  //增加的新方法
5 }

看到上面复杂的继承关系,是不是很眼晕?一想到在开发中要记住这么多的继承关系就感觉整个人就要炸了。不过不要担心,我们可以利用C#提供的的关键字as检查是否继承了某个接口,此法也适用于普通类的继承检查,用好了可以帮我们节省大量功夫。

可以使用 as 运算符执行转换的某些类型在兼容之间的引用类型或可以为null的类型。如下列代码所示:

 1 foreach (Document doc in folder)
 2 {
 3         IStorable isDoc = doc as IStorable;
 4         //如果doc继承了IStorable,则doc转为IStorable
 5         if (isDoc != null)
 6         {
 7                 isDoc.Read();
 8         }
 9         //否则isDoc是null        
10         else
11         {
12                 Console.WriteLine("IStorable not supported");
13         }
14 15 }                     

有时候继承多个接口的时候,会遇到两个接口中定义了签名相同的方法,如下列代码所示:

 1  interface IStorable
 2  {
 3        void Read();
 4        void Write();
 5  }
 6 
 7  interface ITalk
 8  {
 9         void Talk();
10         void Read();
11  }

此时在派生类里定义两个Read方法时就要注意了,定义的方法包括显式定义与隐式定义,如下列代码所示:

 1 public class Document : IStorable, ITalk
 2  {
 3     public Document(string s)
 4      {…; }
 5      // IStorable的Read方法,隐式定义
 6      public virtual void Read()
 7      {…; }
 8      public void Write()
 9      {…; }
10      //ITalk的Read方法,显式定义
11      void ITalk.Read()
12      { …; }
13      public void Talk()
14      { …; }
15 }

需要注意的是显示定义的方法不能有访问修饰符, 隐式为 public

另外需要注意的是两种定义方法的调用问题,如下列代码所示:

1 ...2 //隐式定义的方法正常通过对象调用
3 Document theDoc = new Document(“Test”);
4 theDoc.Read();
5 //显式定义的方法调用时要将对象转为对应接口类型
6 ITalk itDoc = theDoc;
7 itDoc.Read();
8 ...

需要牢记显式实现的接口方法对一般对象是不可见的,无法调用,必须转换类型

本次学习记录到此为止。以后有机会会补上或修正错误之处。

请各位大大不吝赐教!

http://f.hiphotos.baidu.com/zhidao/pic/item/42a98226cffc1e17078acd7a4a90f603738de940.jpg

原文地址:https://www.cnblogs.com/tjulym/p/4392493.html