搜尋
首頁後端開發C#.Net教程詳解C#中抽象類別與介面的區別

詳解C#中抽象類別與介面的區別

Mar 23, 2017 am 11:20 AM
c#抽象類別介面

本文主要介紹了C#中抽象類別與介面的差異。具有很好的參考價值。下面跟著小編一起來看下吧

1.面向介面程式設計和物件導向程式設計是什麼關係

首先,面向介面編程和物件導向程式設計並不是平級的,它並不是比物件導向程式設計更先進的一種獨立的程式設計思想,而是附屬於物件導向思想體系,屬於其一部分。或者說,它是物件導向程式設計體系中的思想精髓之一。

2.接口的本質

接口,在表面上是由幾個沒有主體代碼的方法定義組成的集合體,有唯一的名稱,可以被類別或其他介面所實作(或者也可以說繼承)。它在形式上可能是如下的樣子:

interface InterfaceName
{
 void Method1();
 void Method2(int para1);
 void Method3(string para2,string para3);
}

那麼,介面的本質是什麼呢?或者說介面存在的意義是什麼。我認為可以從以下兩個視角考慮:

1)介面是一組規則的集合,它規定了實現本介面的類別或介面必須擁有的一組規則。體現了自然界「如果你是…就必須能…」的理念。

例如,在自然界中,人都能吃飯,即「如果你是人,就必須能吃飯」。那麼模擬到電腦程式中,就應該有一個IPerson(習慣上,介面名稱由「I」開頭)接口,並有一個方法叫Eat(),然後我們規定,每一個表示「人」的類,必須實現IPerson接口,這就模擬了自然界「如果你是人,就必須能吃」這條規則。

從這裡,我想各位也能看到些許物件導向思想的東西。物件導向思想的核心之一,就是模擬真實世界,把真實世界中的事物抽象成類,整個程式靠各個類別的實例互相通訊、互相協作完成系統功能,這非常符合真實世界的運作狀況,也是面向對象思想的精髓。

2)介面是在某一粒度視圖上同類事物的抽象表示。注意這裡我強調了在某一粒度視圖上,因為「同類事物」這個概念是相對的,它因為粒度視圖不同而不同。

例如,在我的眼裡,我是一個人,和一頭豬有本質區別,我可以接受我和我同學是同類這個說法,但絕不能接受我和一頭豬是同類。但是,如果在一個動物學家眼裡,我和豬應該是同類,因為我們都是動物,他可以認為“人”和“豬”都實現了IAnimal這個接口,而他在研究動物行為時,不會把我和豬分開對待,而會從「動物」這個較大的粒度上研究,但他會認為我和一棵樹有本質區別。

現在換了一個遺傳學家,情況又不同了,因為生物都能遺傳,所以在他眼裡,我不僅和豬沒區別,和一隻蚊子、一個細菌、一顆樹、一個蘑菇甚至一個SARS病毒都沒什麼區別,因為他會認為我們都實現了IDescendable這個接口(註:descend vi. 遺傳),即我們都是可遺傳的東西,他不會分別研究我們,而會將所有生物作為同類進行研究,在他眼裡沒有人和病毒之分,只有可遺傳的物質和不可遺傳的物質。但至少,我和一塊石頭還是有差別的。

可不幸的事情發生了,某日,地球上出現了一位偉大的人,他叫列寧,他在熟讀馬克思、恩格斯的辯證唯物主義思想巨著後,頗有心得,於是他下了一個著名的定義:所謂物質,就是能被意識所反映的客觀實在。至此,我和一塊石頭、一絲空氣、一條成語和傳輸手機訊號的電磁場已經沒什麼區別了,因為在列寧的眼裡,我們都是可以被意識所反映的客觀實在。如果列寧是程式設計師,他會這麼說:所謂物質,就是所有同時實作了「IReflectabe」和「IEsse」兩個介面的類別所產生的實例。 (註:reflect v. 反映  esse n. 客觀實在)

也許你會覺得我上面的例子像在瞎掰,但是,這正是介面得以存在的意義。物件導向思想和核心之一叫做多態性,什麼叫多態性?說穿了就是在某個粒度視圖層面上對同類事物不加區別的對待而統一處理。而之所以敢這樣做,就是因為有介面的存在。像那個遺傳學家,他明白所有生物都實現了IDescendable接口,那隻要是生物,一定有Descend()這個方法,於是他就可以統一研究,而不至於分別研究每一種生物而最終累死。

可能這裡還不能給你一個關於介面本質和作用的直覺印象。那麼在後文的例子和對幾個設計模式的解析中,你將會更直覺地體驗到介面的內涵。

3.面向介面程式設計綜述

那麼什麼是面向介面程式設計呢?我個人的定義是:在系統分析和架構中,分清層次和依賴關係,每個層次不是直接向其上層提供服務(即不是直接實例化在上層中),而是透過定義一組接口,僅向上層暴露其接口功能,上層對於下層僅是接口依賴,而不依賴具體類。

這樣做的好處是顯而易見的,首先對系統彈性大有好處。當下層需要改變時,只要介面及介面功能不變,則上層不用做任何修改。甚至可以在不改動上層程式碼時將下層整個替換掉,就像我們將一個WD的60G硬碟換成一個希捷的160G的硬碟,電腦其他地方不用做任何改動,而是把原硬碟拔下來、新硬碟插上就行了,因為電腦其他部分不依賴具體硬碟,而只依賴一個IDE接口,只要硬碟實現了這個接口,就可以替換上去。從這裡看,程式中的介面和現實中的介面極為相似,所以我一直認為,介面(interface)這個字用的真是神似!

使用介面的另一個好處就是不同部件或層次的開發人員可以並行開工,就像造硬碟的不用等造CPU的,也不用等造顯示器的,只要介面一致,設計合理,完全可以並行進行開發,從而提高效率。

對本文的補充:

#1.關於「面向介面程式設計」中的「介面」與具體物件導向語言中「介面」兩個字

看到有朋友提出「面向介面程式設計」中的「介面」二字應該比單純程式語言中的interface範圍更大。我經過思考,覺得很有道理。這裡我寫的確實不太合理。我想,物件導向語言中的「介面」是指具體的一種程式碼結構,例如C#中用interface關鍵字定義的介面。而「面向介面程式設計」中的「介面」可以說是一種從軟體架構的角度、從一個更抽象的層面上指那種用來隱藏特定底層類別和實現多態性的結構部件。從這個意義上說,如果定義一個抽象類,並且目的是為了實現多態,那麼我認為把這個抽象類別也稱為「介面」是合理的。但是用抽象類別實現多態合理不合理?在下面第二條討論。

概括來說,我覺得兩個「介面」的概念既相互區別又相互連結。 「面向介面程式設計」中的介面是一種思想層面的用於實現多態性、提高軟體靈活性和可維護性的架構部件,而具體語言中的「介面」是將這種思想中的部件具體實施到程式碼裡的手段。

2.關於抽象類別與介面

如果單從具體程式碼來看,對這兩個概念很容易模糊,甚至覺得介面就是多餘的,因為單從具體功能來看,除多重繼承外(C#,Java中),抽象類別似乎完全能取代介面。但是,難道介面的存在是為了實現多重繼承?當然不是。我認為,抽象類別和介面的區別在於使用動機。使用抽象類別是為了程式碼的複用,而使用介面的動機是為了實現多態性。所以,如果你在為某個地方該使用介面還是抽象類別而猶豫不決時,那麼可以想想你的動機是什麼。

看到有朋友對IPerson這個介面的質疑,我個人的理解是,IPerson這個介面該不該定義,關鍵看具體應用中是怎麼個情況。如果我們的專案中有Women和Man,都繼承Person,而且Women和Man絕大多數方法都相同,只有一個方法DoSomethingInWC()不同(例子比較粗俗,各位見諒),那麼當然定義一個AbstractPerson抽象類別比較合理,因為它可以把其他所有方法都包含進去,子類別只定義DoSomethingInWC(),大大減少了重複程式碼量。

但是,如果我们程序中的Women和Man两个类基本没有共同代码,而且有一个PersonHandle类需要实例化他们,并且不希望知道他们是男是女,而只需把他们当作人看待,并实现多态,那么定义成接口就有必要了。

总而言之,接口与抽象类的区别主要在于使用的动机,而不在于其本身。而一个东西该定义成抽象类还是接口,要根据具体环境的上下文决定。

再者,我认为接口和抽象类的另一个区别在于,抽象类和它的子类之间应该是一般和特殊的关系,而接口仅仅是它的子类应该实现的一组规则。(当然,有时也可能存在一般与特殊的关系,但我们使用接口的目的不在这里)如,交通工具定义成抽象类,汽车、飞机、轮船定义成子类,是可以接受的,因为汽车、飞机、轮船都是一种特殊的交通工具。再譬如Icomparable接口,它只是说,实现这个接口的类必须要可以进行比较,这是一条规则。如果Car这个类实现了Icomparable,只是说,我们的Car中有一个方法可以对两个Car的实例进行比较,可能是比哪辆车更贵,也可能比哪辆车更大,这都无所谓,但我们不能说“汽车是一种特殊的可以比较”,这在文法上都不通。

C#.NET里面抽象类和接口有什么区别?

接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。

抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。

人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它.

所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。

下面接着再说说两者在应用上的区别:

接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。

而抽象类在代码实现方面发挥作用,可以实现代码的重用

模板方法设计模式是抽象类的一个典型应用

最佳答案:

1抽象类

(1) 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法

(2) 抽象类不能被实例化

(3) 抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这个类声明为抽象类

(4) 具体派生类必须覆盖基类的抽象方法

(5) 抽象派生类可以覆盖基类的抽象方法,也可以不覆盖。如果不覆盖,则其具体派生类必须覆盖它们。如:

using System;
public abstract class A //抽象类A 
{ 
 private int num=0;
 public int Num //抽象类包含属性 
 { 
  get 
  { 
   return num; 
  } 
  set 
  { 
   num = value; 
  }   
 }
 public virtual int getNum() //抽象类包含虚方法 
 { 
  return num; 
 }
 public void setNum(int n) // //抽象类包含普通方法 
 { 
  this.num = n; 
 }
 public abstract void E(); //类A中的抽象方法E  
}
public abstract class B : A //由于类B继承了类A中的抽象方法E,所以类B也变成了抽象类 
{
}
public class C : B 
{ 
 public override void E() //重写从类A继承的抽象方法。如果类B自己还定义了抽象方法,也必须重写 
 { 
  //throw new Exception("The method or operation is not implemented."); 
 } 
}
public class Test 
{ 
 static void Main() 
 { 
  C c = new C(); 
  c.E(); 
 } 
}

二、接 口

(1) 接口不能被实例化

(2) 接口只能包含方法声明

(3) 接口的成员包括方法、属性、索引器、事件

(4) 接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员。如:

public delegate void EventHandler(object sender, Event e);
public interface ITest 
{ 
 //int x = 0;
 int A 
 { 
  get; 
  set; 
 }
 void Test();
 event EventHandler Event; 
 int this[int index] 
 { 
  get;
  set; 
 } 
}

(5) 接口中的所有成员默认为public,因此接口中不能有private修饰符

(6) 派生类必须实现接口的所有成员

(7) 一个类可以直接实现多个接口,接口之间用逗号隔开

(8) 一个接口可以有多个父接口,实现该接口的类必须实现所有父接口中的所有成员

三、抽象类和接口

相同点:

(1) 都可以被继承

(2) 都不能被实例化

(3) 都可以包含方法声明

(4) 派生类必须实现未实现的方法

区 别:

(1) 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。

(2) 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接口总是后带able字段,证明其是表述一类“我能做。。。”

(3) 接口可以被多重实现,抽象类只能被单一继承

(4) 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中

(5) 抽象類別是從一系列相關物件中抽像出來的概念, 因此反映的是事物的內部共通點;介面是為了滿足外部呼叫而定義的一個功能約定, 因此反映的是事物的外部特性

(6) 介面基本上不具備繼承的任何特定特點,它僅僅承諾了能夠呼叫的方法   

(7) 介面可以用來支援回呼,而繼承並不具備這個特點

(8) 抽象類別實作的具體方法預設為虛的,但實作介面的類別中的介面方法卻預設為非虛的,當然您也可以宣告為虛的

(9) 如果抽象類別實作接口,則可以把接口中方法映射到抽象類別中作為抽象方法而不必實現,而在抽象類別的子類別中實作介面中方法

以上是詳解C#中抽象類別與介面的區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
c#.net的持續相關性:查看當前用法c#.net的持續相關性:查看當前用法Apr 16, 2025 am 12:07 AM

C#.NET依然重要,因為它提供了強大的工具和庫,支持多種應用開發。 1)C#結合.NET框架,使開發高效便捷。 2)C#的類型安全和垃圾回收機制增強了其優勢。 3).NET提供跨平台運行環境和豐富的API,提升了開發靈活性。

從網絡到桌面:C#.NET的多功能性從網絡到桌面:C#.NET的多功能性Apr 15, 2025 am 12:07 AM

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C#.NET與未來:適應新技術C#.NET與未來:適應新技術Apr 14, 2025 am 12:06 AM

C#和.NET通過不斷的更新和優化,適應了新興技術的需求。 1)C#9.0和.NET5引入了記錄類型和性能優化。 2).NETCore增強了雲原生和容器化支持。 3)ASP.NETCore與現代Web技術集成。 4)ML.NET支持機器學習和人工智能。 5)異步編程和最佳實踐提升了性能。

c#.net適合您嗎?評估其適用性c#.net適合您嗎?評估其適用性Apr 13, 2025 am 12:03 AM

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

.NET中的C#代碼:探索編程過程.NET中的C#代碼:探索編程過程Apr 12, 2025 am 12:02 AM

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#.NET:探索核心概念和編程基礎知識C#.NET:探索核心概念和編程基礎知識Apr 10, 2025 am 09:32 AM

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

測試C#.NET應用程序:單元,集成和端到端測試測試C#.NET應用程序:單元,集成和端到端測試Apr 09, 2025 am 12:04 AM

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

高級C#.NET教程:ACE您的下一次高級開發人員面試高級C#.NET教程:ACE您的下一次高級開發人員面試Apr 08, 2025 am 12:06 AM

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具