面向对象--接口与抽象类

面向对象--接口与抽象类的恩恩怨怨 
 
作者:hunanboy 来自:cnblogs 天道酬勤博客
 

接口与抽象类是面向对象编程中两个非常重要的角色,二者各自起着非常重要的作用。但是很多初学的朋友往往会对使用接口还是抽象类存在的很大的迷惑。就我自己的一点心得,发表一下拙见。

面向对象的一些回顾:

面向对象世界中有一个古老的法则:接口隔离原则,指的是不要把多个功能全部都集中在一个接口里面。接口实现的功能要相对单一;衍生开来可以得到另外一个结论:对一组或者称一系列功能的实现,尽量定义相对功能单一的小模块来实现这一组功能。这其实也是解耦和的体现。

那这跟我们的接口和抽象类有什么关系呢?那又得摆出另外一个法则:依赖倒置原则,针对接口编程而不是针对实现编程。

说到这,又会有一个新的问题蹦出来,这是自相矛盾啊,既然要针对接口编程还要抽象类干吗使?我们经常说面向对象,面向对象是来源于生活的。是人们要把对现实世界中的一系列方法论应用到程序设计当中来。 从对象这一概念的引入我们就可以揣摩这一点。人类社会中有很多对象的概念,人、车、物体。不幸的是用程序来实现这些对象比在概念上定义对象要难很多。
(如果能达成这一共识,您可以继续往下看,否则就请看官您移步至留言讨论吧)

MS给出开发者的建议是,用抽象类来实现接口。子类再继承基类。

实例说明:

为什么要这么建议?OK,我们试着结合实际来说明一下这个问题吧。我们要造车。这个车有个基本的属性就是能移动、还必须有轮子。那我们就设计一个接口


 1public interface ICar
 2    {
 3        string Wheel
 4        {
 5            get;
 6            set;
 7        }

 8        void Move();
 9    }

10

接下来的事情,就是实现了。造什么车都行,继承一下就行。随着科技的发展,我们的车想要飞了。此时当然不能修改这个接口,因为要遵循开闭原则。为什么要遵循?我们可以想一下,人坐上飞机能飞上天。但是也没见谁认为人有会飞这个特性的。那也好办,不许修改,那我再加一个接口。


1interface IFlyable
2    {
3        void Fly();
4    }

5

好,我们的飞行汽车最后应该是这样的。


 1class FlyCar : ICar,IAerocraft
 2    {
 3        private string wheel = string.Empty;
 4
 5        public void Fly()
 6        {
 7            Console.WriteLine("{0}车飞起来了",this.wheel);
 8        }

 9        public string Engine
10        {
11            get
12            {
13                return wheel;
14            }

15            set
16            {
17                wheel = value;
18            }

19        }

20
21        public void Move()
22        {
23            Console.WriteLine("{0}轮车在走",this.wheel);
24        }

25    }

26

看起来很不错,车能飞能走了。那它现在他的祖宗到底车还是飞行器呢?我们自己在心里辩论一下吧。估计不是很容易辩清楚。

我们前面说过,面向对象的思想来源于现实生活。如果把这组例子引入到现实中来,造会飞的汽车。肯定是要在原有的汽车上面下功夫。比如你装上喷气动力装置,或者装上翅膀。这只属于扩展功能,而不能说是继承基类。但上面的例子可以明显的看出,我们的飞行汽车已经成了杂交品种。分不出到底是车还是飞行器了。这里就可以知道为什么C#和JAVA都不支持多重继承基类了。避免杂交,减少耦合。

上面把车定义成接口并不完美,我们知道,一辆正常的车肯定能移动。这是天生的本质,不需要任何实现。但是上面还需要子类来实现这个功能。从这一点其实可以衍生出很多问题来。我们这里不做过多讨论。

重新设计这个系统。我们可以把移动,飞行都看成是一种行为。我们的车本身拥有Move这个行为,是构成车基类的基本要素。


 1interface IMoveable
 2    {
 3        void Move();
 4    }

 5    interface IFlyable
 6    {
 7        void Fly();
 8    }

 9public abstract class Car : IMoveable
10    {
11        public abstract string Wheel
12        {
13            get;
14            set;
15        }

16        public virtual void Move()
17        {
18            Console.WriteLine("车移动了");
19        }

20    }

21    public sealed class FlyCar : Car,IFlyable
22    {
23        private string wheel = string.Empty;
24        public override string Wheel
25        {
26            get
27            {
28                return wheel;
29            }

30            set
31            {
32                wheel = value;
33            }

34        }
        
35
36        public void Fly()
37        {
38            base.Move();
39            Console.WriteLine("汽车起飞成功!");
40        }

41    }

42    //在这里应用任何模式都很简单了
43    static void Main(string[] args)
44    {       
45            FlyCar c = new FlyCar();
46            ((IFlyable)c).Fly();
47            ((Car)c).Move();
48    }

49

总结归纳: 其实类似的例子在我们的.NET Library里随处可见,例如Control类是继承于Component和其他大量的接口的,而他们的基类却是MarshalByRefObject。因为他们归功到底又属于引用对象。

从上面的描述中,我们可以得出结论:

接口:是某类行为或功能的抽象。是一种开关或者是契约。所以从字面上来理解就非常清楚了,西方神话中有很多和魔鬼定下契约来使自己的力量得到提升的故事。你必须定下这个契约才能得到你想要的力量。

抽象类:对具体对象的最高抽象,这个对象拥有自己的最基本特征。

所以,从整体上来讲,抽象类和接口本质上都是是系统的最高抽象。从实际上来讲,二者抽象的对象不一样,就这一点导致了他们二者的应用的截然不同。

技术原创作品,请尊重他人劳动成果,转载请注明出处;不得用于任何商业形式活动,否则将追究法律责任


Interface   versus   Class   Inheritance   is   pretty   easy   once   you   understand   it.   
There   is   a   very   easy   way   to   distinguish   the   2.   
Class   inheritance   =   implemenation   inheritance.   
What   this   means   is   that   if   you   have   a   base   object   you   inherit   from,   your   new   derived   object   will   either   contain   or   override   the   existing   functionality   of   the   base   object.   This   is   often   referred   to   as   "is   a "   relationship.   
A   Beagle   IS   A   Dog.   
Interface   inheritance   is   a   little   different.   It   is   basically   like   a   contract   and   is   usually   referred   to   as   a   "has   a "   relationship.   By   agreeing   to   implement   an   interface,   you   agree   to   implement   all   of   its   members,   and   provide   your   own   implementation.   An   Interface   should   describe   what   a   class   does,   rather   than   what   a   class   is.   
A   Beagle   Has   A   Bark   
One   reason   to   use   Interfaces   over   Implementations   is   versioning   or   upgradability.   
Any   changes   you   make   to   your   base   class   (abstract   class)   could   possibly   break   subclasses   that   are   derived   from   that   class.   By   implementing   interfaces   you   alleviate   this   problem   by   allowing   clients   or   code   to   have   multiple   interfaces.   By   using   interfaces,   subclass   can   only   see   its   parents   interface,   not   the   implementation.   

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值