这个问题基本上可以说是 面试时的必问问题
C# 中的接口和抽象类
相同点:
1. 都不能直接实例化,都可以通过继承实现其抽象方法
2. 都是面向抽象编程的技术基础,实现了诸多的设计模式
不同点:
1. 接口支持多继承 (类可以继承任意多个接口),抽象类不能实现多继承 (一个类最多只能继承一个抽象类) (C#中不支持多继承)
2. 接口只能定义抽象规则; 抽象类既可以定义规则,还可以提供已经实现了的成员
3. 接口是一组行为规范;抽象类是一个不完全的类,着重族的概念
4. 接口可以用于支持回调;抽象类不能实现回调,因为继承不支持
5. 接口只能包含方法,属性,索引器,事件的签名四种成员类型, 但是不能定义字段,不能包含已经实现的方法; 抽象类可以定义属性,也可以定义字段,包含已经实现了的方法
抽象类中可以包含 字段,构造函数, 析构函数,静态成员,常量. 接口不可以
6. 接口可以作用于值类型和引用类型; 抽象类只能作用于引用类型。 比如 Struct就可以继承接口,但是不能继承类
7. 接口中的成员必须是公有的, 接口中包含的成员不带访问修饰符,所有接口成员都隐式规定为public的.
抽象类和子类是 "is-a"关系,而接口是不同类间共有的状态或行为的规范
一个类继承了某个抽象类,表示它 "是什么"
实现了某个接口表示它“有什么功能”或者“会做什么事”
eg: 燕子(具体类)是鸟(抽象类), 会飞(接口)。 C#中不支持多继承,即 燕子 只能是鸟,不会是其他东西了; 但它可以有多个功能,做很多事情,比如会飞( 接口 IFly), 会吃( 接口IEat)
8. 一个类或结构实现接口的原则是: 要么全要要么全不要。即所有在接口中定义的成员都必须在实现它的类或结构中实现.
9. 好的接口定义应该是具有专一功能的,而不是多功能的,否则造成接口污染.
如果一个类只是实现了这个接口中的一个功能,而不得不去实现接口中的其他方法,这就叫做接口污染 (因为一个类实现接口,必须实现它的所有方法)
10. 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中的方法
11. 对抽象类不能使用new关键字,也不能被密封. 如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类, 另外,实现抽象方法由override关键字来实现。
12. 当一个类继承某个接口时,它不仅要实现该接口定义的所有方法,还要实现该接口从其他接口中继承的所有方法
13. 接口多定义对象的行为,着重于CAN-DO关系类型;抽象类多定义对象的属性,偏重于IS-A式的关系。