关于接口

     接口是体现面向对象编程思想优越性的一件利器,为什么这么说呢?首先我们来看,接口是为继承而存在的,如果没有继承,那就自然不需要接口了,既然有继承,那就需要把可能被多个类所继承的一些公共部分抽象出来,接口封装的就是这些公共的行为规范(方法定义),类可以通过继承多个接口来丰富自己的行为机制,但是在C#中,类是不可以继承多个类的。C#最显著的特点就是极大地提高了程序的开发效率和维护效率,所以对于继承多个类这种容易引起二义性的机制是深恶痛绝的。

我们都是由学生时代一路走过来的,所以我想借用学生时代的那些行为规范来作为现实生活中的接口的例子。

读小学的时候,我们至少会有两套行为规范:小学生行为规范和少先队员行为规范。首先我们都得遵守小学生行为规范,其次如果是少先队员,就还得遵守少先队员行为规范。我们对于这两套行为规范不列举太多细节规则,每套一条就够了,首先,作为少先队员,过马路时要先看红绿灯:

   1: interface IPupilRule
   2: {
   3:     void CrossTheRoad(int trafficLightIndex);
   4: }

在IPupileRule中,我们定义了“过马路看红绿灯”这样的行为规范,它其实就是一个函数声明,定义了函数名、返回值类型以及参数类型等信息,但是并没有函数体。对,接口中只能有函数定义这样的指导性原则,不允许存在函数体,至于具体的实现细节,那就“具体问题具体分析”吧。接下来我们再来定义少先队员行为规范,也不列举太多细则,一条足矣,少先队员不能抽烟:

   1: interface IYoungPioneerRule
   2: {
   3:     void NoSmoke();
   4: }

同样的,只有函数声明没有实现细节,因为行为守则这样的东西只能告诉你作为一名光荣的少先队员是绝对不能抽烟的,它不会也不能面面俱到地告诉你假如你叔叔阿姨给你递烟应该如何谢绝,假如你爸爸教你抽烟应该如何拒绝,另外假如那些辍学的坏孩子强迫你抽烟又该如何反抗等等。废话不多说,否则真成了“提供函数体的接口”了。

既然接口是不提供函数实现细节的,那么当一个小学生需要横过马路的时候,就只能靠他自己来完成具体的逻辑实现了:

   1: public class Pupil : IPupilRule
   2: {
   3:     /// <summary>
   4:     /// Cross the road and notice the traffic light.
   5:     /// </summary>
   6:     /// <param name="trafficLightIndex">The index of traffic light.</param>
   7:     public void CrossTheRoad(int trafficLightIndex)
   8:     {
   9:         switch (trafficLightIndex)
  10:         {
  11:             case 0:     // Red, stop.
  12:                 break;
  13:             case 1:     // Yellow, stop.
  14:                 break;
  15:             case 2:     // Green, go.
  16:                 break;
  17:             default:    // Unknown situation, thinking.
  18:                 break;
  19:         }
  20:     }
  21: }

接下来,少先队员出场了。首先我们来分析一下这个场景,少先队员是需要遵守少先队员行为规范的小学生。由此可见,少先队员需要实现前面提到的两种行为规范中的所有规定,这也就体现了接口的好处,可以实现多重继承。当然,在本文所用的例子当中,少先队员大可不必重新继承并实现IPupilRule接口了,他既然是一名小学生,那就可以继承Pupil这个类,而且他并不需要改变Pupil中对小学生行为规范的具体实现细节,他只需要自己实现少先队员行为规范中的规定就行了。

   1: public class YoungPioneer : Pupil, IYoungPioneerRule
   2: {
   3:     /// <summary>
   4:     /// Young pioneer should help other people.
   5:     /// </summary>
   6:     public void NoSmoke()
   7:     {
   8:         throw new NotImplementedException("I can't smoke because I'm a young pioneer.");
   9:     }
  10: }

另外,接口也是可以继承接口的,并且可以多重继承。我们假设有一个向阳小学,这个学校还有自己的校规,校规内容不多,主要是要求学生要严格遵守小学生行为规范和少先队员行为规范,并且都要会唱校歌。

   1: interface IXiangYangSchoolRule : IPupilRule, IYoungPioneerRule
   2: {
   3:     void SingSchoolSong();
   4: }

因此这套校规编写起来倒不麻烦,继承了两套现成的行为规范并且增加一点儿自己的要求就行了。向阳小学的每一位学生都得遵守这套校规:

   1: public class XiangYangPupil : IXiangYangSchoolRule
   2: {
   3:     public void SingSchoolSong()
   4:     {
   5:         Console.WriteLine("I love Xiang Yang School!");
   6:     }
   7:  
   8:     public void CrossTheRoad(int trafficLightIndex)
   9:     {
  10:         throw new NotImplementedException();
  11:     }
  12:  
  13:     public void NoSmoke()
  14:     {
  15:         throw new NotImplementedException();
  16:     }
  17: }

通过上面的介绍,您大概已经对如何使用接口有了一些初步的认识,当面对实际问题的时候,只要合理地分析和设计,接口一定会为我们的开发工作带来很大的便利!

Pupil

0
0
(请您对文章做出评价)
posted @ 2008-06-16 08:53 Autumoon 阅读(1778) 评论(10)   编辑 收藏 网摘 所属分类: 白话C#系列

Body:31.25,BeforeCate:0,0,Total:46.875

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值