日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

浅谈C#中的多态及相关知识(主要内容来自msdn) -转载(benzite)

發(fā)布時間:2025/5/22 C# 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈C#中的多态及相关知识(主要内容来自msdn) -转载(benzite) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄:

一、抽象類

二、接口

三、抽象類和接口的使用

四、類和接口的區(qū)別

五、覆蓋與隱藏


一、?抽象類:?

?????? ?用abstract修飾的類叫抽象類。抽象類是特殊的類,只是不能被實例化;除此以外,具有類的其他特性;重要的是抽象類可以包括抽象方法,這是普通類所不能的。抽象方法只能聲明于抽象類中,且不包含任何實現,派生類必須覆蓋它們。?

??????? 用abstract修飾的方法叫抽象方法。abstract 修飾符可以和類、方法、屬性、索引器及事件一起使用。一個抽象方法只包含方法頭而且沒有實現代碼。當一個類有一個或多個抽象方法時,此類本身必須聲明為abstact。一個抽象類不能實例化.因為它包含有沒有實現的方法。

??????? 在類聲明中使用 abstract 修飾符以指示某個類只能是其他類的基類。標記為抽象或包含在抽象類中的成員必須通過從抽象類派生的類來實現。

????? ?另外,抽象類可以派生自一個抽象類,可以覆蓋基類的抽象方法也可以不覆蓋,如果不覆蓋,則其派生類必須覆蓋它們。


二、接口:


?????? 接口是引用類型的,類似于類,更和抽象類有所相似,以至于很多人對抽象類和接口的區(qū)別比較模糊。和抽象類的相似之處有三點:

1、不能實例化;
2、包含未實現的方法聲明;
3、派生類必須實現未實現的方法,抽象類是抽象方法,接口則是所有成員(不僅是方法包括其他成員);另外,接口有如下特性:

??????? 接口除了可以包含方法之外,還可以包含屬性、索引器、事件,而且這些成員都被定義為公有的。除此之外,不能包含任何其他的成員,例如:常量、域、構造函數、析構函數、靜態(tài)成員。
一個類可以直接繼承多個接口,但只能直接繼承一個類(包括抽象類)。

接口實例

?11?public?delegate?void?Del();?
?22?public?interface?ITest?
?33?{?
?4???4?//int??a?=?null;?
?5???6?int?A?
?6??7??{?
?7??8?????get;?
?8??9??}
?
?9????10?
10??11?void?Test();?
11??12?event?Del?OnDel;?
12??13?int?this[int?index]?
13??14?{?
14????15?get;?
15????16?set;?
16??17?}
?
1718?}
?


注意!還有另外一種類不能被實例化:
所有構造函數都被標記為private,這種類也是不能被實例化的,嚴格的說是不能在類外被實例化,可以在此類的內部實例化(這種方式可以用于實現單件設計模式)。注意一點,這樣的類也不能夠作為基類來繼承。

三、抽象類和接口的使用


?????? ?抽象類用于部分實現一個類,再由用戶按需求對其進行不同的擴展和完善;接口只是定義一個行為的規(guī)范或規(guī)定。
抽象類在組件的所有實現間提供通用的已實現功能;接口創(chuàng)建在大范圍全異對象間使用的功能。
抽象類主要用于關系密切的對象;而接口適合為不相關的類提供通用功能。
抽象類主要用于設計大的功能單元;而接口用于設計小而簡練的功能塊。

例如:

??????? Window窗體可以用抽象類來設計,可以把公有操作和屬性放到一個抽象類里,讓窗體和對話框繼承自這個抽象類,再根據自己的需求進行擴展和完善。
打印操作可以作為一個接口提供給每個需要此功能的窗體,因為窗體的內容不同,就要根據他們自己的要求去實現自己的打印功能。打印時只通過接口來調用,而不用在乎是那個窗體要打印。


-----------------------

四、類和接口有何區(qū)別

??????? 從書上摘下來的,還是比較好懂的:

1.抽象類是一個不完全的類,需要進一步專業(yè)化.接口只是一個行為的規(guī)范或規(guī)定;
2.接口基本上不具備繼承的任何具體特點,它僅僅承諾了能夠調用的方法;
3.一個類一次可以實現若干個接口,但是只能擴展一個父類
4.接口可以用于支持回調,而繼承并不具備這個特點.
有些直接就是接口與類的區(qū)別.第四點我不是很明白......
一個類如果要實現某個接口,除非它實現了該接口中承諾的所有方法,否則(即未實現或者僅僅實現部分方法),該類必須被聲明為抽象類.而該類的子類也繼承了這一特性.

override和new的區(qū)別
new是覆蓋override是重載。???
????
“覆蓋”并不意味著“刪除”???
????
示例:

?1?using???System;???
?2??class???A???
?3??{???
?4????????public???void???F()?????
?5????????{???
?6??????????????Console.WriteLine("A.F");?????
?7????????}
???
?8??}
???
?9??class???B:???A???
10??{???
11????????new???public???void???F()?????
12????????{?????
13??????????????Console.WriteLine("B.F");?????
14????????}
???
15??}
???
16??class???Test???
17??{???
18????????static???void???Main()?????
19????????{???
20??????????????B???b???=???new???B();???
21??????????????b.F();???
22??????????????A???a???=???b;?????
23??????????????a.F();???
24????????}
???
25??}
???
輸出為??
? B.F??
? A.F???
????
但“重載”意味著“刪除”,這就是“覆蓋”和“重載”的區(qū)別。如下列:

?1using???System;???
?2??class???A???
?3??{???
?4????????public???virtual???void???F()?????
?5????????{???
?6??????????????Console.WriteLine("A.F");?????
?7????????}
???
?8??}
???
?9??class???B:???A???
10??{???
11????????public???override???void???F()?????
12????????{?????
13??????????????Console.WriteLine("B.F");?????
14????????}
???
15??}
???
16??class???Test???
17??{???
18????????static???void???Main()?????
19????????{???
20??????????????B???b???=???new???B();???
21??????????????b.F();???
22??????????????A???a???=???b;?????
23??????????????a.F();???
24????????}
???
25??}
???


輸出為??
B.F??
B.F??

abstract 與 virtual

??????? abstract與virtual: 方法重寫時都使用 override 關鍵字,interface中的方法和abstract方法都要求實現。調用虛方法時,將為重寫成員檢查該對象的運行時類型。將調用大部分派生類中的該重寫成員,如果沒有派生類重寫該成員,則它可能是原始成員。

virtual標記方法為虛方法

1.可在派生類中以override覆蓋此方法
2.不覆蓋也可由對象調用
3.無此標記的方法(也無其他標記),重寫時需用new隱藏原方法

virtual 方法

???????? 若一個實例方法的聲明中含有 virtual 修飾符,則稱該方法為虛擬方法。若其中沒有 virtual 修飾符,則稱該方法為非虛擬方法。
非虛擬方法的實現是不會變的:無論是在聲明它的類的實例上調用該方法還是在派生類的實例上調用,實現都是相同的。與此相反,一個虛擬方法的實現可以由派生類取代。取代所繼承的虛擬方法的實現的過程稱為重寫該方法(第 10.5.4 節(jié))。
在一個虛擬方法調用中,該調用所涉及的那個實例的運行時類型確定了要被調用的究竟是該方法的哪一個實現。在非虛擬方法調用中,相關的實例的編譯時類型是決定性因素。準確地說,當在具有編譯時類型 C 和運行時類型 R 的實例(其中 R 為 C 或者從 C 派生的類)上用參數列表 A 調用名為 N 的方法時,調用按下述規(guī)則處理:
?????? 首先,將重載決策應用于 C、N 和 A,以從在 C 中聲明的和由 C 繼承的方法集中選擇一個特定的方法 M。第 7.5.5.1 節(jié)對此進行了描述。?

?????? 然后,如果 M 為非虛擬方法,則調用 M。否則(M 為虛擬方法),就會調用就 R 而言 M 的派生程度最大的那個實現。對于在一個類中聲明的或者由類繼承的每個虛擬方法,存在一個就該類而言的派生程度最大的實現。就類 R 而言虛擬方法 M 的派生度最大的實現按下述規(guī)則確定:?

????? ?如果 R 中含有關于 M 的 virtual 聲明,則這是 M 的派生程度最大的實現。否則,如果 R 中含有關于 M 的 override 聲明,則這是 M 的派生程度最大的實現。否則,就 R 而言 M 的派生程度最大的實現與就 R 的直接基類而言 M 的派生程度最大的實現相同。?

??????下列實例闡釋虛擬方法和非虛擬方法之間的區(qū)別:

?1using?System;
?2class?A
?3{
?4???public?void?F()?{?Console.WriteLine("A.F");?}
?5???public?virtual?void?G()?{?Console.WriteLine("A.G");?}
?6}

?7class?B:?A
?8{
?9???new?public?void?F()?{?Console.WriteLine("B.F");?}
10???public?override?void?G()?{?Console.WriteLine("B.G");?}
11}

12class?Test
13{
14???static?void?Main()?{
15??????B?b?=?new?B();
16??????A?a?=?b;
17??????a.F();
18??????b.F();
19??????a.G();
20??????b.G();
21???}

22}

???????? 在該示例中,A 引入一個非虛擬方法 F 和一個虛擬方法 G。類 B 引入一個新的非虛擬方法 F,從而隱藏了繼承的 F,并且還重寫了繼承的方法 G。此例產生輸出:
A.F
B.F
B.G
B.G

??????? 請注意,語句 a.G() 實際調用的是 B.G 而不是 A.G。這是因為,對調用哪個實際方法實現起決定作用的是該實例的運行時類型(即 B),而不是該實例的編譯時類型(即 A)。
由于一個類中聲明的方法可以隱藏繼承來的方法,因此同一個類中可以包含若干個具有相同簽名的虛擬方法。這不會造成多義性問題,因為除派生程度最大的那個方法外,其他方法都被隱藏起來了。在下面的示例中:
?1using?System;
?2class?A
?3{
?4???public?virtual?void?F()?{?Console.WriteLine("A.F");?}
?5}

?6class?B:?A
?7{
?8???public?override?void?F()?{?Console.WriteLine("B.F");?}
?9}

10class?C:?B
11{
12???new?public?virtual?void?F()?{?Console.WriteLine("C.F");?}
13}

14class?D:?C
15{
16???public?override?void?F()?{?Console.WriteLine("D.F");?}
17}

18class?Test
19{
20???static?void?Main()?{
21??????D?d?=?new?D();
22??????A?a?=?d;
23??????B?b?=?d;
24??????C?c?=?d;
25??????a.F();
26??????b.F();
27??????c.F();
28??????d.F();
29???}

30}


????????C 類和 D 類均含有兩個具有相同簽名的虛擬方法:A 引入的虛擬方法和 C 引入的虛擬方法。但是,由 C 引入的方法隱藏了從 A 繼承的方法。因此,D 中的重寫聲明所重寫的是由 C 引入的方法,D 不可能重寫由 A 引入的方法。此例產生輸出:
B.F
B.F
D.F
D.F

請注意,通過訪問 D 的實例(借助一個派生程度較小的類型,它的方法沒有被隱藏起來),可以調用被隱藏的虛擬方法。

五、覆蓋與隱藏

覆蓋:
覆蓋即重寫,重寫是指重寫基類的方法,在基類中的方法必須有修飾符virtual,而在子類的方法中必須指明override。

格式:

基類中:
public virtual void myMethod()
?{
?}
子類中:
public override void myMethod()
?{
?}
重寫以后,用基類對象和子類對象訪問myMethod()方法,結果都是訪問在子類中重新定義的方法,基類的方法相當于被覆蓋掉了。

隱藏:

子類重定義父類的方法(函數聲明一致),實現重定義只需要加上關鍵字new;
如果沒有添加關鍵字new,那么編譯器將默認添加new;
隱藏的成員是早綁定。

轉載于:https://www.cnblogs.com/cnkenny/archive/2007/09/29/910979.html

總結

以上是生活随笔為你收集整理的浅谈C#中的多态及相关知识(主要内容来自msdn) -转载(benzite)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。