



























相同点
不同点
共性、个性与选择
有的书上写到C#中推荐使用接口(Interface)来替代抽象基类(Abstract Class),并强调使用接口的诸多好处,这点我不敢苟同,从上面列表中看来,两者之间还是存在不少差异的,而这种差异的存在性必然决定了适用场景的不同,例如在抽象基类中可以为部分方法提供默认的实现,从而避免在子类中重复实现它们,提高代码的可重用性,这是抽象类的优势所在;而接口中只能包含抽象方法。至于何时使用抽象基类何时使用接口关键还是取决于用户是如何看待继承类之间的联系的,用户更加关心的是它们之间的个性差异还是它们之间的共性联系。举个生活中的例子加以说明。
如果给你三个对象分别是人、鱼、青蛙,让你为他们设计个基类来概括它们之间的联系,那么首先给你的感觉肯定是它们个体间的差异性较大,很难抽象出共性,然而若让你概括他们行为之间的共性,你可能想了想会意识到他们都会游泳,只不过是游泳方式迥异。那么这时你就应当考虑使用接口而不是抽象基类,原因有三条:
设计为:
1 interface ISwim
2 {
3 void Swim();
4 }
5
6 public class Person : ISwim
7 {
8 public void Swim()
9 {
10 //Swimming in person's style.
11 }
12 }
13
14 public class Frog : ISwim
15 {
16 public void Swim()
17 {
18 //Swimming in frog's style.
19 }
20 }
21
22 public class Fish : ISwim
23 {
24 public void Swim()
25 {
26 //Swimming in fish's style.
27 }
28 }
好,这时再给你三个对象,分别是鲫鱼、鲤鱼、金鱼,仍然让你设计基类来概括它们之间的联系,那么你第一个意识到的肯定是它们都属于鱼类,其次是他们游泳的方式可能稍有差异,这时就应当使用抽象基类而不是接口,对比着上面的例子,原因也有三条:
设计为:
1 abstract public class Fish
2 {
3 abstract public void Swim();
4 }
5
6 public class 鲫鱼 : Fish
7 {
8 public override void Swim()
9 {
10 //Swim like a 鲫鱼
11 }
12 }
13
14 public class 鲤鱼 : Fish
15 {
16 public override void Swim()
17 {
18 //Swim like a 鲤鱼
19 }
20 }
21
22 public class 金鱼 : Fish
23 {
24 public override void Swim()
25 {
26 //Swim like a 金鱼
27 }
28 }
总结:
观察在使用接口或是使用抽象基类的几条理由中,第三条理由其实是一样的,它所描述的是面向对象中多态的概念,即通过覆盖父类的方法来实现,在运行时根据传递的对象引用,来调用相应的方法。第二条理由开始产生分歧,接口更加强调了继承对象间具有相同的行为,而抽象类同时还强调了继承对象间具有相同的属性。而真正将接口与抽象基类区分开的则是理由一,归纳如下:
转载自(http://www.cnblogs.com/shenfx318/archive/2007/01/25/630760.html)
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。