C#抽象类和接口孩子间在对于抽象类定义的支持方面具备很大的类似性,甚至能够相互替换,所以不少开发者在进行抽象类定义时对于抽象类和接口的选择显得比较随意。其实,二者之间仍是有很大区别的。web
首先说一下接口与抽象类的异同:面试
相同点:ide
1.他们都不能实例化本身,也就是说都是用来被继承的。spa
2.抽象类中的抽象方法和接口方法同样,都不能有方法体code
不一样点:orm
1.抽象类里能够有字段,接口中不能有字段.blog
2.抽象类中的普通方法能够有方法体,而接口方法没有方法体。继承
3.接口中的方法不能有访问修饰符,抽象类中的抽象方法被继承,须要override重写 .接口
4.接口更像是一种规范,一种约束。ci
5.一个子类只能继承一个抽象类,但却能够继承多个接口。
接下来是抽象方法和虚方法的异同:
其实能够把抽象方法看作是没有方法体的虚方法。
相同点:
1.抽象方法和虚方法均可以被重写。
不一样点:
1.abstract 和virtual的关键字不一样
2.抽象方法必定没有方法体,而虚方法能够有方法体。
下面写个例子说明一下:
/// <summary> /// 一个手机的抽象类 /// </summary> public abstract class Mobilephone { private string _logo; public string Logo { get { return _logo; } set { _logo = value; } } public abstract void Call(); public virtual void Callagain() { Console.WriteLine("我再打一个电话"); } } /// <summary> /// 定义一个实体类,继承了一个抽象类及多个接口 /// </summary> public class Nokia :Mobilephone,IClock,Ilistenmusic { public override void Call() { Console.WriteLine("NOKIA打电话没问题"); } public void clock() { Console.WriteLine("NOKIA的手机也有闹钟功能"); } public void listenmusic() { Console.WriteLine("NOKIA的手机还能听歌"); } public override void Callagain() { Console.WriteLine("算了,仍是不打了"); } } /// <summary> /// 下面定义了两个接口,为了说明能够继承多个接口 /// </summary> public interface Ilistenmusic { void listenmusic(); } public interface IClock { void clock(); }
在补充一个小例子,
这里有到颇有意思的面试题,说名了new关键字和override的区别:
class Program { static void Main(string[] args) { B5 b5 = new B5(); b5.MethodB(); } } public class A5 { public virtual void MethodA() { Console.WriteLine("A5.MethodA"); Console.Read(); } public virtual void MethodB() { MethodA(); } } public class B5 :A5 { public new void MethodA() { Console.WriteLine("B5.MethodA"); Console.ReadLine(); } } class Program { static void Main(string[] args) { B5 b5 = new B5(); b5.MethodB(); } } public class A5 { public virtual void MethodA() { Console.WriteLine("A5.MethodA"); Console.Read(); } public virtual void MethodB() { MethodA(); } } public class B5 :A5 { public new void MethodA() { Console.WriteLine("B5.MethodA"); Console.ReadLine(); } }
最后的答案是:"A5.MethodA"