C#类、接口、虚方法和抽象方法-抽象类与接口的区别与联系
C#抽象類和接口之間在對于抽象類定義的支持方面具有很大的相似性,甚至可以相互替換,因此很多開發者在進行抽象類定義時對于抽象類和接口的選擇顯得比較隨意。其實,兩者之間還是有很大的區別的。首先,以抽象類的方式定義一個公共的抽象類Animal如下:
public abstract class Animal???
{
??? public abstract void Run();
??? public abstract void Eat();
}
注意:類中默認的范圍是private, 一定要顯式將抽象的內容顯示聲明為public
然后使用接口的方式定義接口Animal如下:
public interface IAnimal
{
??? abstract void Run();
??? abstract void Eat();
}
注意:雖然在.NET中不再主張匈牙利命名法,但是在使用接口的時候還是習慣上加上大寫字母“I”以表示接口。
抽象類和接口的相同點:
1)都是通過繼承實現,而不能直接實例化,
如:Animal animal = new Animal();???????????????????????? //錯誤!
或者:IAnimal animal = new IAnimal();?????????????????????? //錯誤!
抽象類和接口通過關鍵字new實例化都是錯誤的!!
注意:這里要說明一點,任何接口都是不可能實例化的,除了抽象類,一般的類都是可以實例化,而且如果可以實例化,那么它一定是一個非抽象類。
2)都有沒有實現的抽象方法,抽象方法僅僅是一個對方法的定義并沒有具體的實現,只有在派生的使用override進行重寫才能得到實現。
如下面所示:Animal和IAnimal都定義了的兩個方法Run()和Eat()
???
abstract void Run();
abstract void Eat();??????????????????
它們并沒有實現真正的內容,你并不知道Run或者Eat到底是怎么Run或者Eat的,只是知道這兩個函數的存在,定義存在的作用在于,只要定義了那么雖然不知道怎么實現,但是可以確定這兩個方法對于一般Animal來說都應該是存在的,派生的時候才會根據不同的派生類的特點實現所需要的功能,從而也完成了多態的實現,同時要注意一點,如果存在這樣的的情況,比如Run對鳥類可能不實用,同時Fly對于陸地的動物也一樣不存在,多態的實現辦法是不處理,而不處理本身也是多態。
下面我們以Animal和IAnimal為基礎,分別以抽象類和接口的方式派生出 一個DOG類。
代碼如下:????
??? public abstract class Dog : Animal?????? //從Animal類派生出Dog類
??? {
??????? override void Run()
??????? {
??????????? Console.WriteLine("Dog runs.");
??????? }
??????? override void Eat()
??????? {
??????????? Console.WriteLine("Dog eat.");
??????? }
??? }
????? //從IAnimal接口派生出Dog類
????? public abstract class Dog : IAnimal
??? {
??????? override void Run()
??????? {
??????????? Console.WriteLine("Dog runs.");
??????? }
??????? override void Eat()
??????? {
??????????? Console.WriteLine("Dog eat.");
??????? }
?? }???????????????
我們從上面可以看出,實現的方法是完全一樣的,沒有什么區別。
接口和抽象類的區別:
共同點是比較容易理解的,但是兩者的區別更是要知道,下面把兩者的區別先列出來,然后舉例說明:
1)接口支持多繼承,抽象類不能實現多繼承;
???? public interface IEat
??? {
??????? abstract void Eat();
??? }
??? public interface IRun
??? {
??????? abstract void Run();
??? }
??? public class Dog : IEat, IRun
??? {??????? …
??? }
以上實現了IEat和IRun兩個接口,在Dog類派生時實現。
2)接口只能定義抽象規則;抽象類既可以定義規則,還可能提供已實現的成員,下面的Eat就得到了實現,只有類可以實現。
public abstract class Animal
{
???? abstract void Run();
???? public void Eat()
???? {
???????? Console.WriteLine("Animal Eat.");
???? }
}??????
3)接口是一組行為規范,只提供方法,主要強調方法重寫(override)的概念,可以理解為一個不完全的類,而抽象類中還可以有屬性,事件等內容,同時既可以有初值也可以完全抽象。
4)接口只包含方法、屬性、索引器、事件的簽名,但不能定義字段和包含實現的方法;抽象類可以定義字段、屬性、包含有實現的方法。
???? public abstract class Animal
??? {
??????? string animalName;
??????? //非抽象屬性
??????? public string AnimalName
??????? {
??????????? get { return animalName; }
??????????? set { animalName = value; }
??????? }
?????????? //抽象屬性
??????? public abstract float Weight
??????? {
??????????? get;
??????????? set;
??????? }
??????? public abstract void Run();
??????? public void Eat()
??????? {
??????????? Console.WriteLine("Animal Eat.");
??????? }
??? }????????????????
5) 接口可以作用于值類型和引用類型;抽象類只能作用于引用類型。例如,Struct就可以繼承接口,而不能繼承類。
總結:
應該說,接口的使用面比抽象類更廣一些,而抽象類比接口更具限制性,但是功能上更加強大,體現的是繼承關系。當類的發展不需要受到限制和約束時,我們可以使用接口,此類可以自由的發展,此時繼承接口的這個類就是一個穩定的類,這也體現了接口保持類的穩定性。這兩者具備有很大的相似性,都源于面向對象思想,在使用何時抽象類,何時接口并沒有一個定論,應該根據自己程序的大小、設計的方式、程序發展的空間來看,這就需要扎實的理論基礎和大量的實踐經驗了。
總結
以上是生活随笔為你收集整理的C#类、接口、虚方法和抽象方法-抽象类与接口的区别与联系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样梦到前世记忆
- 下一篇: 【年少的风】C#小学生算式×××2