C#中抽象类和接口的异同

抽象类

通过在类定义前面放置关键字 abstract,可以将类声明为抽象类。抽象类不能实例化。 抽象类的用途是提供一个可供多个派生类共享的通用基类定义。 例如,类库可以定义一个抽象类,将其用作多个类库函数的参数,并要求使用该库的程序员通过创建派生类来提供自己的类实现。

抽象类可以包含非抽象的方法、属性以及抽象的方法、属性。抽象类和抽象方法都必须在派生类中用override进行重写。

抽象方法:抽象类也可以定义抽象方法。 方法是将关键字 abstract 添加到方法的返回类型的前面。抽象方法没有实现,所以方法定义后面是分号,而不是常规的方法块。抽象方法只能声明于抽象类中,且不包含任何实现。抽象类的派生类必须实现所有抽象方法。 当抽象类从基类继承虚方法时,抽象类可以使用抽象方法重写该虚方法。

抽象属性抽象属性声明不提供属性访问器的实现,它只声明该类支持属性,而将访问器实现留给派生类。参考:https://msdn.microsoft.com/zh-cn/library/yd3z1377(v=vs.110).aspx

接口

参考:https://msdn.microsoft.com/zh-cn/library/ms173156.aspx

接口是引用类型,可以实现相关一组功能的定义。接口可以包含方法、属性、事件、索引器,或者这四个成员类型的任意组合。 接口不能包含常数、字段、运算符、实例构造函数、析构函数或类型。 接口成员将自动是公共的,因此,它们不会包含任何访问修饰符。 成员也不能是 静态。若要实现接口成员,实现的选件类的相应成员必须是公共的,非静态的,并且具有名称和签名和接口成员相同。

接口具有下列属性:
- 接口与抽象基类。 实现接口的任何选件类或结构必须实现其所有成员的链接。
- 接口不能直接实例化。 其成员通过实现接口的任何选件类或结构实现。
- 接口可以包含事件、索引器、方法和属性。
- 接口不包含方法的实现。
- 选件类或结构可以实现多个接口。 选件类可以继承基类并实现一个或多个接口。

相同点

接口是引用类型的,类似于类,和抽象类的相似之处有三点:
      1. 不能实例化;
      2. 包含未实现的方法声明;
      3. 派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);

不同点

     1. 类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类“我能做。。。”。抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中;
      2. 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;
      3. 一个类一次可以实现若干个接口,但是只能扩展一个父类;
      4. 接口可以用于支持回调,而继承并不具备这个特点;
      5. 抽象类不能被密封;
      6. 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的;
      7.(接口)与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上;
      8. 抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现;
      9. 好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染;
     10. 尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知。(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如 asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则;
     11.如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法。 

参考:http://kb.cnblogs.com/page/41836/


C#中抽象类和接口的异同

上一篇:[C#] 如何把void*转换为byte[]


下一篇:解决windows 10 9926 中vmware安装的虚拟机无法桥接上网的问题