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"