C#接口

本文的观点不仅仅适用于C#语言。

 

我们能够接触到“接口”(interface)这个词语的地方有很多。操作系统中,UI(User Interface,用户界面)、GUI(图形用户界面),API(Application Programming Interface),…;接口,本身就是一门课程;C++、C#、Java语言中的接口;软件工程中,也常常提及模块与模块之间或者子系统和子系统之间的接口;等等。

 

如果汇总一下,我们不难发现,接口是用于两个实体或对象之间交互的。对于某个体而言,接口是用于与外界交互的。UI/GUI是操作系统与用户交互的;API是操作系统与程序员交互的;…。

 

有这样两个关键词:交互、对外。交互是指接口应该是一个或一组行为,因为交互是一个动词。对外是指接口的这些行为必须对外公开。现在,我们来看C#中对于接口的定义:(1)成员只能是属性、方法或者事件,这三者都是行为(属性本质上也是方法,事件是一种特殊的委托,而委托正是对行为的抽象);(2)接口中所有成员都是public的,既然都是公共的,那就不需要写public关键字。

 

 

接口体现了一种多面性
我们来考察下面的例子:


一个人,在父母面前是子女,也就是说,Ta将使用作为子女应该具有的行为与父母打交道。而这个人,在朋友面前将使用作为朋友应该具有的行为与朋友打交道。那么,对于人而言,就有两个接口:作为子女的接口(IChild)和作为朋友的接口(IFriend)。这是多面性的第一个体现。


在父母面前,作为子女可以撒娇(行为),但在朋友面前就不方便撒娇,因此撒娇这个行为是作为IChild时应该具有的。在父母面前还可以啼哭(行为),在朋友面前也可以啼哭,但是我们所有的人都明白,作为子女的啼哭其目的、方式都可能不同于作为朋友的啼哭。现在就出现了同一个人,都叫做“啼哭”这个名字的行为却有着不同的行为方式,这也体现出一个个体或对象的多面性(这种多面性在C#中通过接口的显式实现来表达)。正所谓,见人说人话,见鬼说鬼话!

 

 

字段与接口
我们知道,类或结构中的实例字段是此类或结构的对象实际占用内存的部分。这些字段类似于构成一个人的水、蛋白质、细胞等等,这些是实际占用自然资源的物质。而行为是一种与时间相关的过程,也就是四维空间中的物体。正是具有这些行为,我们才能感知由水、蛋白质、细胞等构成的这个物体是具有生命的,因为Ta能够同我们进行交互。因此,生命的最终意义体现在行为。


构成一个对象的组成部分是不容许被外部破坏和直接访问到的,只能通过此对象具有的主动或被动行为,我们才能感知Ta的身高、体重,才能知道Ta会说话、走路。这就是为什么,虽然C#中字段可以不是private,但是通常建议定义为private,然后使用属性包装字段。

事实上,一个类或结构,也许应该封装成两个部分:一组字段和一组接口。而不是现在看到的一组字段和一组方法。

 

从这种分离中,我们将很容易推导出接口的另外一个特性:抽象性。

 

 

接口是抽象的
当我们与朋友交流时,也许我们根本不关心构成Ta的那些物质(水、脂肪、蛋白质)有多少,是什么形态、颜色等等。我们需要知道,Ta具有作为朋友的一面,通过这一面我们能够与Ta进行交互即可。与父母交互亦是如此。


我们吃一个苹果根本不需要关心构成这个苹果的有哪些元素、水分子数目多少,我们只需要知道这个苹果能够被吃到嘴里即可。当我们用一台苹果时,我们不需要知道内部结构是怎样的,构成它的那些部件如何排列的,我们只需要知道,它有键盘能够我们进行输入,它有屏幕能够显示给我们阅读。

 

我们还不需要关心的是,朋友啼哭是怎么一个生理机制,由哪些小动作组成;键盘输入时字符如何一步一步传递给CPU再显示在屏幕上的。

 

也就是说,在接口上,我们不关心某一个接口行为是如何实现的,我们只需要一个对象具有这样一个接口,而这个接口上具有一个这样的行为,这就足够了。


也就是说,接口中的行为可以不用考虑实现。

 

 

仅有这些还不够。同一个接口可以被不同类别的对象拥有(或者叫做实现)。比如,人类就喜欢将宠物当做子女来看待,此时我们家里养的狗也就实现了IChild接口。那就是说,IChild可以被人实现,也可以被狗实现。如果可能,还可以被桌子实现。无论是神马东西,只要实现了IChild接口,无论是神马东西,只要实现了IParent接口,那么这两种对象之间就可以形成父母与子女的关系。

 

因此,接口不关心字段,接口也不关心行为的实现,接口也没法关心行为的实现,因为不同的对象对同一个接口的同一个方法的实现方式可能完全不同。


面试题目中,通常会问到接口,接口与抽象类等。总结起来:
(1) 接口是行为的集合:一组相关行为的集合。行为可以是属性、方法、事件。
(2) 接口行为是公共的:因为要与外界交互。
(3) 接口是抽象的:其中所有的行为没有实现。
(4) 接口不关心对象的构成:因此接口中不包含字段。没有字段,当然不会有构造函数,更不会有析构函数。

 

 

接口的不变性
在COM(组件对象模型)中,接口有一个很重要的特性,就是接口的不变性。这一点在C#语言中,微软没有刻意强调。
接口的不变性基本思想就是如果在1.0中定义了这样一个接口:
interface IFriend
{
 void Cry();
}

到了2.0时,我们需要对这个接口进行扩展,因为我们发现朋友之间还经常大笑。那么是不是直接在1.0的接口上修改呢?
interface IFriend
{
 void Cry();
 void Laugh();
}

接口的不变性不建议这么做,而是使用如下的方式进行扩展:
interface IFriend2 : IFriend
{
void Laugh();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值