.net的接口和抽象类的异同


          多态性、封装、继承是面向对象思想的三大特性,接口和抽象类都在面向对象语言中体现这些特性,其用法有点相似,但又有诸多不同。下面就来总结一下他们在.net下用法的异同。
          
          1、什么是多态性(Polymorphism)?:

          按字面的意思就是“多种形状”。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function) 实现的。

          多态性是允许将父对象设置成为和一个和多个它的子对象相等的技术,比如Parent:=Child; 

          赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。
   
         2、接口表示一个完全抽象类,它包含一组虚方法的签名(signature),其中每一个方法都有名称、参数和返回值,但没有具体的实现,CLR允许接口可以包含事件、属性、索引器、静态方法、静态字段、静态构造函数以及常数,但C#中不能包含任何静态成员,一个类实现某个接口时,它要实现该接口的所有方法,还要实现该接口从其他接口中继承的所有方法,一个类可以实现多个接口。接口在继承体系中体现的是一种“as a”或者是“do as”的关系,其注重的是不相关(差异较大)的多个类之间的相似的行为,体现差异较大的对象间在功能上的共性。
         
        3、顾名思义,抽象类是包含抽象方法的类,抽象类为派生类提供公共定义,它必须包含抽象方法,也可以包含非抽象方法,抽象类不能被实例化。必须由派生类实现其抽象方法,因此抽象类不能是密封类(sealed)。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类,派生类实现抽象方法由overriding修饰符来实现。抽象类在继承体系中体现一种“is a”的关系,着重族的概念,体现共性较多的对象间功能上的差异。
       
      4、相同点      

        都不能被直接实例化,都可以通过继承实现其抽象方法。  
        都体现了面向对象的基础特性,在应用程序的设计方面提供了非常优秀的抽象的特性。

      5、不同点  

        接口支持多继承;抽象类不能实现多继承。
 
       接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员。
 
       接口是一组行为规范;抽象类是一个不完全的类,着重族的概念。 

       接口可以用于支持回调;抽象类不能实现回调,因为继承不支持。

       接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。 

      接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。例如,Struct就可以继承接口,而不能继承类。

     总结:
           在设计当中接口和抽象类各有优劣,当在差异较大的对象间寻求功能上的共性时,使用接口;当在共性较多的对象间寻求功能上的差异时,使用抽象基类。
           如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。
          如果创建的功能将在大范围的全异对象间使用,则使用接口。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。 
          如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。 
          如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。抽象类允许部分实现类,而接口不包含任何成员的实现。


        
    

posted @ 2008-05-18 16:52  忠歌  阅读(185)  评论(0编辑  收藏  举报