接口

从广义上说,凡是一个类提供给外部使用的部分都可以被称为接口。但是在引入继承和抽象类之前,这个广义接口并没有太大的意义。广义接口的真正意义是在类的继承中体现多态的功能,这种接口又被称为抽象接口。

狭义接口是指特定的函数集合,一般是用Interface声明的,它表示一个方法集合,这个集合被称为一个命名接口。一个命名接口中的方法必须在一个类中实现后才能被使用。

一个类继承实现一个接口,称为这个类实现了该接口。一个接口可以被多个类实现,一个类也可以继承多个接口,这样就形成了一种灵活的接口调用方式,从而实现更加灵活和节省资源的多态。

 

接口是另一种“is a” 关系

继承被看作是一种“is a ”关系(即派生类型同时也是基类类型)。对接口的实现,是另一种形式的“is a”关系:

如果Professor类扩张自Person类,则教授(Professor)也是人(person);

如果Professor类实现ITeacher接口,则教授(Professor)同时也是教师(teacher)。

同样,如果A类实现接口X,则所有派生自A的类都实现同一个接口。例如,如果从Professor类派生出AdjunctProfessor类,如果Professor类实现了ITeacher接口,则副教授(AdjunctProfessor)也是教师。

public class Professor :ITeacher

{

     //ITeacher所需要的所有方法将被本类实现....细节从略

}

public class AdunctProfessor:Professor

{

    //ITeacher类所需要的所有方法,至少是从Professor继承的下来的那些方法都被本类实现...细节从略。

}

这很容易理解,因为AdjunctProfessor类将从Professor类继承ITeacher接口要求的所有方法,或者覆载这些方法;AdjunctProfessor类也将所有能力执行ITeacher接口的服务。

 

实现多个接口

举个例子,如果我们创建第二个接口,名为IAdministrator,它定义了一下方法头:

public interface IAdministrator

{

    bool approveNewCourse(Course c);

    bool hireProfessor(Professor p);

}

我们可以把Professor类声明为同时实现ITeacher和IAdministrator 接口,这样,这个类就得实现两个接口的所以方法。

public class Professor :ITeacher,IAdministrator

{

    //Professor 类必须实现ITeacher接口要求的方法...细节从略

    //Professor类必须实现IAdministrator接口要求的方法....细节从略

}

注意,如果一个类实现的两个或多个接口中的方法拥有相同的方法签名,则在实现类中只需要实现其中一个——该方法将同时满足所有接口的实现要求。

一个类实现了超过一个接口,它的对象就有能力扮演应用程序中的多种身份或角色;这样的对象可以为不同类型的引用变量所维系。根据上述定义,Professor既是ITeacher又是IAdministrator,下面的客户代码时可能存在的:

//实例化一个Professor对象,将其句柄放在一个类型为Professor的引用变量中。

Professor  p = new Professor();

 

//然后声明两个引用变量,类型分别为Professor类实现的两个接口类型。

ITeacher t;

IAdministrator a;

t = p ;   //把Professor 对象的句柄放在类型为Teaher的引用变量中,这是可以的,因为教授同时也是老师!

a=p;    //把Professor对象的句柄放在类型为Administrator的引用变量中,这是可以的,因为教授可能同时也是行政人员!

可见,一个Professor对象可以被Professor、ITeaher和IAdministrator类型的引用变量所维系,因为教授是教师,教授也可能是行政人员。Professor对象拥有三种身份

这个概念等同于作为一个人的你,被不同人当作不同的角色看待的情形:在经理眼里你是雇员,在父母眼里你是孩子,在孩子眼里你是父母,如此等等。

我们可以把一个对象当做Professor来要求....

//Department 是为Professor类定义的属性

p.Department =“Computer Science”;

 

或者当做为一个Teacher....

//AgreeToTeach是为ITeacher接口定义的方法....

t.AgreeToTeach(c);   //注意p.AgreeToTeach(c);也同样可以工作......

 

或者当作一个行政人员.....

//ApproveNewCourse是为IAdministrator接口定义的方法.....

a.approveNewCourse(c); //注意p.approveNewCourse(c);也同样可以工作....

因为它身兼三职!

 

接口和实例化

接口不能被实例化,因为接口中没有构造函数。也就是说,如果把ITeacher定义为一个接口,则不能将它实例化:

ITeacher  t  =new ITeacher(); //不能这样做!编译器将报错

error CS0144: Cannot create an instance of the abstract class or interface 'ITeacher'

虽然我们不能实例化一个接口,但却能把引用变量声明为一个接口类型:

ITeacher t; //这样可以

上面一行可以通过,下面一行也可以:

ITeacher t = new Professor();

为什么?如果等号右边的表达式的类型与左边变量的类型匹配,编译器就允许赋值操作。Professor类实现了ITeacher 接口,教授就是老师,所以这种赋值是被允许的。

 

接口的重要性

只要有可能,就应该把类的公共部分设计为接口,而不是设计为特定的类类型,这样就可以让方法在多个方面拥有更多灵活性,诸如:

方法的形参

方法的返回值

下面用两个例子来展示接口的威力。

例一

在本例中,假定

Professor是Person的一个派生类;

Student是Person的一个派生类;

Professor 和Student是兄弟类——相互不继承;

Person实现ITeacher接口,所以Professor和Student也间接地实现了ITeacher接口。

我们从设计一个名为Course的类开始,该类有一个类型为Professor的私有字段,名为teachingAssistant,和访问这个字段的属性。

public class Course

{

    private Professor TeachingAssistant

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值