Mail to Keith Dan
keith的天空
海阔凭鱼跃,天高任鸟飞
posts - 29,comments - 177,trackbacks - 2

我发现,不少朋友对于接口这个东西,理论还是比较清楚,但是说不出所以然,对于其应用更加模糊.
借助上面写的一个小程序,讲一下接口问题。
大家可以去下载<<C#象棋游戏>>,互相学习,呵呵。
首先,我们进入今天的主题,接口(interface)用来定义一种程序的协定,这样的概念相信大家都知道,在C#中接口允许多继承,允许包含事件,方法,属性等。
其次,我们再来看,接口,顾名思义,从名字上我们也能看出为一种连接的出入口,那么在我们程序中也是一种出入通道(特别是组件编程)的感觉。

我们来看这个程序,我们先假设这个程序由2个程序员来做,A做棋盘,B做棋子,我们其实也可以不使用接口来做,那么我们A在棋子点击事件中需要写成

private void cib_Click(object sender, EventArgs e)
{
if(sender is ChessItemBing){}
else if(sender is ChessItemJu){}
else if(sender is ChessItemMa){}
else if(sender is ChessItemPao){}

}

当然,在这个程序中类不多,只有7个,大家可以一一判断,此时A必须知道B如何创建类,创建了那些类,但是如果有很多这样的类呢,由或者几个月以后程序有改变呢?会发现,A必须随着B变化而变化,可扩充性非常的差。

那么我们再来看,其中有一个接口,定义了整个棋子的各类属性以及方法。A程序员并不需要知道B程序员创建了那些类,B程序员也不需要知道A程序的代码,AB只需要知道他们的出入口为IChessItem,A所要做的工作只是转换获取该接口

private void cib_Click(object sender, EventArgs e)
        
{

            IChessItem ic 
= (IChessItem)sender;

}

那么B呢,大家可以看到,几个月以后,如果程序有改变,B要做的仅仅是添加类继承此接口,只要接口没改变,那么A的程序可以不做任何的修改。

我们再回过头来看此程序,象棋的棋子有7种,都继承类ChessItemBase,而ChessItemBase他则继承接口,实现这些方法。IChessItem作为模板,也可以说它作为和我们棋盘的通道出入口,棋盘并不知道棋子实际是那一个类,他们所有的超做都来自此接口。

那么可能有朋友会问,我转换为父类也同样能达到效果嘛

private void cib_Click(object sender, EventArgs e)
{
ChessItemBase cib 
= (ChessItemBase )sender;
}

说的不错,在我们这个程序中确实如此,但如果我们程序扩充,添加另一父类ChessItemBase2,ChessItemBase3呢,你会发现,A还是要重写判断为ChessItemBase,ChessItemBase2,ChessItemBase3,的代码,所以这都不利于我们程序的扩充。

接口比较抽象,看到许多书上,以及网上很多文章对接口写的很书面化,很多人看的云里雾里,所以上了这边文章.
以上是我对接口的一个个人理解,可能语言不太专业,可能大家对此持有其他不同的意见,欢迎发表.

posted on 2006-12-06 17:43 KeithDan 阅读(1712) 评论(8)  编辑 收藏 所属分类: 中国象棋

FeedBack:
2006-12-06 19:34 | 代码乱了      
哈哈
不错,只是有好几个错别字,推敲下才知道意思
  回复  引用  查看    
2006-12-06 21:27 | 航天奇侠      

接口 就是一个类的函数规范。
一个类 “继承”一个接口,等于说这个类必须提供接口所要求的所有函数。

比如接口{ void hello();}继承的类型就要包括这个函数。
然后我们不用知道该类的其他细节,只要知道他是继承这个接口约定的,那么调用这个接口约定的函数就是合法的。

其实应该多用接口来进行各种类型的通讯桥梁,原因是这样的:
1。类的继承发展没有理由受另一个类所约束,因为受一个外类所影响,我们可以适应,但是受两个呢,三个呢?只有杜绝这种可能,保持独立性,才能保证类是忠于自身需要的。
2。接口同时保证了使用该类得代码的稳定性。



  回复  引用  查看    
2006-12-07 09:15 | 雨恨云愁 [未注册用户]
但如果我们程序扩充,添加另一父类ChessItemBase2,ChessItemBase3呢,你会发现,A还是要重写判断为ChessItemBase,ChessItemBase2,ChessItemBase3,的代码,所以这都不利于我们程序的扩充。


难道你用接口的话就不要去改变谁是谁了?
既然他们都能有一个统一的接口
我把ChessItemBase,ChessItemBase2,ChessItemBase3 都继承自一个父类ChessItem,而这个父类拥有所有基本的方法 传递的时候不是也一样不需要变么?
private void cib_Click(object sender, EventArgs e)
{
ChessItem cib = (ChessItem )sender;
}
  回复  引用    
#4楼 [楼主]
2006-12-07 09:25 | KeithDan      
@雨恨云愁

楼上这位朋友,我写的可能口语化一些,其实2楼的朋友已经补充的非常好了,
我们之所以使用接口,为的程序具备有良好的可扩充性,那么这种可扩充的可能正是来自于航天奇侠所说的"类的继承发展没有理由受另一个类所约束,因为受一个外类所影响,我们可以适应,但是受两个呢,三个呢?只有杜绝这种可能,保持独立性,才能保证类是忠于自身需要的。"

  回复  引用  查看    
2006-12-07 09:45 | oldmoon [未注册用户]
我理解的接口是一个规范,前面的人写好这个规范,后面的就必须去遵守
  回复  引用    
2006-12-08 23:10 | life[匿名] [未注册用户]
不错啊,此文通俗易懂,加上2楼的所说的,令我豁然开朗
  回复  引用    
2007-05-24 09:33 | 8      
好文,谢谢
  回复  引用  查看    
2007-10-18 11:04 | ASDFGHJKL [未注册用户]
5L的不错 谢了~
  回复  引用    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-07-08 14:06 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: