接口有什么好处?什么情况下用? 给我讲讲?谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://msdn.microsoft.com/zh-cn/library/87d83y5b(VS.80).aspx 我们在设计和编写程序的时候,有很多模块或者说是业务逻辑是会变化的,这会给我们在程序设计时带来很多不便,因为这些变化可能很小,但是我们却需要用不同的方法来实现,也许你会说“我可以用重载或重写”,但当这样的设计很多时就很难理解了。所以这时我们需要一个很好的设计原则,那就是“把可能需要变化之处独立出来,不要和那些不变的代码混在一起”。就是说,把会变化的部分取出来并封装,好让其他部分不会受到影响。结果呢?变化带给我们的后果没有想象中的那么严重了,我们设计的系统变得更有弹性了。 我们也可以这样思考:把会变化的部分取出来并封装起来,以便以后可以轻易地改动或扩充该部分,而不会影响不需要改变的其他部分。 如果你能领悟上面的意思,那么我下面就提出另一个原则:针对接口编程,而不是针对实现编程。 以前我们可能会这么想:我们的某些行为(也就是我们的一些动作,方法)来自超类的具体实现或继承某个接口并有子类来实现。但是这样的做法都是依赖与“实现”,我们被实现绑定,没有办法更改行为。 所以我们以后要针对接口编程,它的关键就在多态。利用多态,程序可以针对超类型编程,执行时会很据具体状态执行真正的行为,不会被帮死到超类的行为上。我想如果你能理解多态,上面这句话你肯定也能理解。 举个例子,说明一下多态: class Duck{ quack(){ //鸭子超类的方法,说明每个鸭子都会叫,如果有些个别的鸭子有很好的天赋可以唱歌,那么就让它自己重新写吧。} ... } class ADuck extends Duck{ ... } class BDuck extends Duck{ ... } class main(){ Duck d1= new ADuck(); Duck d2 = new BDuck(); // 这里d1,d2都是Duck类型,但是它们却不是同一个子类的对象。实际运行时它们肯定不同。 //当然这里说的针对超类型编程,说的是,变量的声明类型是超类型,通常是一个抽象类或接口,如此,只要是实现以超类型的类所产生的对象,都可以指定给这个变量。 } 现在问题来了,我们的设计有些变化,我们的鸭子不只需要叫,还需要飞。那么这时你的想法是什么呢?在超类中放入fly方法,然后如果子类有需要就重写?如果是这样那就错了。万一以后有些鸭子不会飞,可怎么办,我们已经有了fly方法,呵呵。 所以这个时候用接口就是最好的了。 我们首先定义一个接口 public interface FlyBehavior{ void fly(); } 然后每个子类如果有会飞的能力,那我们绝对不会埋没人才,呵呵,让它实现FlyBehavior接口吧,然后自己来做具体的动作。 class CDuck extends Duck,FlyBehavior{ void fly(){ //重新实现自己想要的动作行为,实现了接口就必须这个接口的所有方法,所以这里必须实习fly方法,除非这个类是抽象类 } } 你现在可能觉得,这样是不是得对每个会飞的鸭子实现具体的方法啊,可是很多方法是一样的啊,这样我们不是重复了么? 我这里还有一部分没有说,你继续看 我们定义一个类来实现刚才的接口 public class FlyWithWings extends FlyBehavior{ public void fly(){ //这里我们写下具体的飞行方法 } } 然后修改我们刚才定义的鸭子C(CDuck ) class CDuck extends Duck,FlyBehavior{ FlyBehavior flyWithWings; CDuck(){ //我们在构造函数中初始化这个会飞的能力类 flyWithWings = new FlyWithWings(); } void fly(){ flyWithWings.fly(); } } 这样我们的杰作完成了,我们应用好多的知识。你自己总结一下吧! 我也只是写了接口的一部分功能,还有很多,我学的一不好,慢慢领悟吧,这里我引用了很多《head first设计模式》书的话和例子 使用C#进行office开发中,如何隐藏Word工具菜单栏? 于目标机器积极拒绝,无法连接 C#清除绘图 显示背景图片 为什么我的winform画面之间切换时CPU占用率会这么高呢??? 初学WEB编程问题之一:数据库里表有一个字段类型为bit,如何在C#里把取得的值Object转成boolean类型? c1dockingtab 控件的复制,或是对聊天软件有研究的兄弟姐妹请进! 请问一个C#调用dll的问题 哪位老大有C#开发P2P软件的经验(类似QQ),分享一下。谢谢! sqldatareader的用法 高手请进(在线等) 求一正则表达式 一个简单问题
我们也可以这样思考:把会变化的部分取出来并封装起来,以便以后可以轻易地改动或扩充该部分,而不会影响不需要改变的其他部分。
如果你能领悟上面的意思,那么我下面就提出另一个原则:针对接口编程,而不是针对实现编程。
以前我们可能会这么想:我们的某些行为(也就是我们的一些动作,方法)来自超类的具体实现或继承某个接口并有子类来实现。但是这样的做法都是依赖与“实现”,我们被实现绑定,没有办法更改行为。
所以我们以后要针对接口编程,它的关键就在多态。利用多态,程序可以针对超类型编程,执行时会很据具体状态执行真正的行为,不会被帮死到超类的行为上。我想如果你能理解多态,上面这句话你肯定也能理解。
举个例子,说明一下多态:
class Duck{
quack(){
//鸭子超类的方法,说明每个鸭子都会叫,如果有些个别的鸭子有很好的天赋可以唱歌,那么就让它自己重新写吧。}
...
}
class ADuck extends Duck{
...
}
class BDuck extends Duck{
...
}
class main(){
Duck d1= new ADuck();
Duck d2 = new BDuck();
// 这里d1,d2都是Duck类型,但是它们却不是同一个子类的对象。实际运行时它们肯定不同。
//当然这里说的针对超类型编程,说的是,变量的声明类型是超类型,通常是一个抽象类或接口,如此,只要是实现以超类型的类所产生的对象,都可以指定给这个变量。
}
现在问题来了,我们的设计有些变化,我们的鸭子不只需要叫,还需要飞。那么这时你的想法是什么呢?在超类中放入fly方法,然后如果子类有需要就重写?如果是这样那就错了。万一以后有些鸭子不会飞,可怎么办,我们已经有了fly方法,呵呵。
所以这个时候用接口就是最好的了。
我们首先定义一个接口
public interface FlyBehavior{
void fly();
}
然后每个子类如果有会飞的能力,那我们绝对不会埋没人才,呵呵,让它实现FlyBehavior接口吧,然后自己来做具体的动作。
class CDuck extends Duck,FlyBehavior{
void fly(){
//重新实现自己想要的动作行为,实现了接口就必须这个接口的所有方法,所以这里必须实习fly方法,除非这个类是抽象类
}
}
你现在可能觉得,这样是不是得对每个会飞的鸭子实现具体的方法啊,可是很多方法是一样的啊,这样我们不是重复了么?
我这里还有一部分没有说,你继续看
我们定义一个类来实现刚才的接口
public class FlyWithWings extends FlyBehavior{
public void fly(){
//这里我们写下具体的飞行方法
}
}
然后修改我们刚才定义的鸭子C(CDuck )
class CDuck extends Duck,FlyBehavior{
FlyBehavior flyWithWings;
CDuck(){
//我们在构造函数中初始化这个会飞的能力类
flyWithWings = new FlyWithWings();
} void fly(){
flyWithWings.fly();
}
}
这样我们的杰作完成了,我们应用好多的知识。你自己总结一下吧!
我也只是写了接口的一部分功能,还有很多,我学的一不好,慢慢领悟吧,这里我引用了很多《head first设计模式》书的话和例子