亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

<展現C#> 第五章 類 (2)

2019-11-18 22:06:58
字體:
來源:轉載
供稿:網友

                                第五章  類 (2)

5.3  類屬性
    有兩種途徑揭示類的命名屬性——通過域成員或者通過屬性。前者是作為具有公共訪問性的成員變量而被實現的;后者并不直接回應存儲位置,只是通過 存取標志(accessors)被訪問。
    當你想讀出或寫入屬性的值時,存取標志限定了被實現的語句。用于讀出屬性的值的存取標志記為關鍵字get,而要修改屬性的值的讀寫符標志記為set。
在你對該理論一知半解以前,請看一下清單5.9中的例子,屬性SquareFeet被標上了get和set的存取標志。
清單 5.9  實現屬性存取標志

1: using System;
2:
3: public class House
4: {
5:  PRivate int m_nSqFeet;
6:
7:  public int SquareFeet
8:  {
9:   get { return m_nSqFeet; }
10:   set { m_nSqFeet = value; }
11:  }
12: }
13:
14: class TestApp
15: {
16:  public static void Main()
17:  {
18:   House myHouse = new House();
19:   myHouse.SquareFeet = 250;
20:   Console.WriteLine(myHouse.SquareFeet);
21:  }
22: }

    House類有一個命名為SquareFeet的屬性,它可以被讀和寫。實際的值存儲在一個可以從類內部訪問的變量中——如果
你想當作一個域成員重寫它,你所要做的就是忽略存取標志而把變量重新定義為:
public int SquareFeet;
對于一個如此簡單的變量,這樣不錯。但是,如果你想要隱藏類內部存儲結構的細節時,就應該采用存取標志。在這種情
況下,set 存取標志給值參數中的屬性傳遞新值。(可以改名,見第10行。)
除了能夠隱藏實現細節外,你還可自由地限定各種操作:
get和set:允許對屬性進行讀寫訪問。
get only:只允許讀屬性的值。
set only:只允許寫屬性的值。
除此之外,你可以獲得實現在set標志中有效代碼的機會。例如,由于種種原因(或根本沒有原因),你就能夠拒絕一個新
值。最好是沒有人告訴你它是一個動態屬性——當你第一次請求它后,它會保存下來,故要盡可能地推遲資源分配。

5.4   索引
   你想過象訪問數組那樣使用索引訪問類嗎 ?使用C#的索引功能,對它的期待便可了結。

語法基本上象這樣:
屬性   修飾符  聲明 { 聲明內容}

具體的例子為
public string this[int nIndex]
{
get { ... }
set { ... }
}

索引返回或按給出的index設置字符串。它沒有屬性,但使用了public修飾符。聲明部分由類型string和this 組成用于表
示類的索引。
get和set的執行規則和屬性的規則相同。(你不能取消其中一個。) 只存在一個差別,那就是:你幾乎可以任意定義大括
弧中的參數。限制為,必須至少規定一個參數,允許ref  和out  修飾符。
this關鍵字確保一個解釋。索引沒有用戶定義的名字,this 表示默認接口的索引。如果類實現了多個接口,你可以增加更
多個由InterfaceName.this說明的索引。

  為了演示一個索引的使用,我創建了一個小型的類,它能夠解析一個主機名為ip地址——或一個IP地址列表(以
http://www.microsoft.com為例 )。這個列表通過索引可以訪問,你可以看一下清單5.10 的具體實現。

清單  5.10  通過一個索引獲取一個IP地址

1: using System;
2: using System.Net;
3:
4: class ResolveDNS
5: {
6:  IPAddress[] m_arrIPs;
7:
8:  public void Resolve(string strHost)
9:  {
10:   IPHostEntry iphe = DNS.GetHostByName(strHost);
11:   m_arrIPs = iphe.AddressList;
12:  }
13:
14:  public IPAddress this[int nIndex]
15:  {
16:   get
17:   {
18:    return m_arrIPs[nIndex];
19:   }
20:  }
21:
22:  public int Count
23:  {
24:   get { return m_arrIPs.Length; }
25:  }
26: }
27:
28: class DNSResolverApp
29: {
30:  public static void Main()
31:  {
32:   ResolveDNS myDNSResolver = new ResolveDNS();
33:   myDNSResolver.Resolve("http://www.microsoft.com");
34:
35:   int nCount = myDNSResolver.Count;
36:   Console.WriteLine("Found {0} IP's for hostname", nCount);
37:   for (int i=0; i < nCount; i++)
38:    Console.WriteLine(myDNSResolver[i]);
39:  }  
40: }

     為了解析主機名,我用到了DNS類,它是System .Net 名字空間的一部分。但是,由于這個名字空間并不包含在核心
庫中,所以必須在編譯命令行中引用該庫:
csc /r:System.Net.dll /out:resolver.exe dnsresolve.cs
     解析代碼是向前解析的。在該  Resolve方法中,代碼調用DNS類的靜態方法GetHostByName,它返回一個IPHostEntry
對象。結果,該對象包含有我要找的數組——AddressList數組。在退出Resolve 方法之前,在局部的對象實例成員
m_arrIPs中,存儲了一個AddressList array的拷貝(類型IPAddress 的對象存儲在其中)。
     具有現在生成的數組 ,通過使用在類ResolveDNS中求得的索引,應用程序代碼就可以在第37至38行列舉出IP地址。
(在第6章 "控制語句",有更多有關語句的信息。)   因為沒有辦法更改IP地址,所以僅給索引使用了get存取標志。為了
簡單其見,我忽略了數組的邊界溢出檢查。
  
5.4  事件
   當你寫一個類時,有時有必要讓類的客戶知道一些已經發生的事件。如果你是一個具有多年編程經驗的程序員,似乎有
很多的解決辦法,包括用于回調的函數指針和用于ActiveX控件的事件接收(event sinks)?,F在你將要學到另外一種把客
戶代碼關聯到類通知的辦法——使用事件。
    事件既可以被聲明為類域成員(成員變量),也可以被聲明為屬性。兩者的共性為,事件的類型必定是代表元,而函
數指針原形和C#的代表元具有相同的含義。
    每一個事件都可以被0或更多的客戶占用,且客戶可以隨時關聯或取消事件。你可以以靜態或者以實例方法定義代表
元,而后者很受C++程序員的歡迎。
    既然我已經提到了事件的所有功能及相應的代表元,請看清單5.11中的例子。它生動地體現了該理論。

清單5.11  在類中實現事件處理
1: using System;
2:
3: // 向前聲明
4: public delegate void EventHandler(string strText);
5:
6: class EventSource
7: {
8:  public event EventHandler TextOut;
9:
10:  public void TriggerEvent()
11:  {
12:   if (null != TextOut) TextOut("Event triggered");
13:  }
14: }
15:
16: class TestApp
17: {
18:  public static void Main()
19:  {
20:   EventSource evsrc = new EventSource();
21:   
22:   evsrc.TextOut += new EventHandler(CatchEvent);
23:   evsrc.TriggerEvent();
24:
25:   evsrc.TextOut -= new EventHandler(CatchEvent);
26:   evsrc.TriggerEvent();
27:
28:   TestApp theApp = new TestApp();
29:   evsrc.TextOut += new EventHandler(theApp.InstanceCatch);
30:   evsrc.TriggerEvent();
31:  }
32:
33:  public static void CatchEvent(string strText)
34:  {
35:   Console.WriteLine(strText);
36:  }
37:
38:  public void InstanceCatch(string strText)
39:  {
40:   Console.WriteLine("Instance " + strText);
41:  }
42: }

    第4行聲明了代表元(事件方法原形),它用來給第8行中的EventSource類聲明TextOut事件域成員。你可以觀察到代
表元作為一種新的類型聲明,當聲明事件時可以使用代表元。
    該類僅有一個方法,它允許我們觸發事件。請注意,你必須進行事件域成員不為null的檢測,因為可能會出現沒有客
戶對事件感興趣這種情況。
    TestApp類包含了Main 方法,也包含了另外兩個方法,它們都具備事件所必需的信號。其中一個方法是靜態的,而另
一個是實例方法。
    EventSource 被實例化,而靜態方法CatchEvent被預關聯上了 TextOut事件:
evsrc.TextOut += new EventHandler(CatchEvent);
    從現在起,當事件被觸發時,該方法被調用。如果你對事件不再感興趣,簡單地取消關聯:
evsrc.TextOut -= new EventHandler(CatchEvent);
    注意,你不能隨意取消關聯的處理函數——在類代碼中僅創建了這些處理函數。為了證明事件處理函數也和實例方法
一起工作,余下的代碼建立了TestApp 的實例,并鉤住事件處理方法。
    事件在哪方面對你特別有用?你將經常在asp+中或使用到WFC (Windows Foundation Classes)時,涉及到事件和代表
元。

5.5   應用修飾符
    在這一章的學習過程中,你已經見過了象public、virtual等修飾符。欲以一種易于理解的方法概括它們,我把它們劃
分為三節:

。類修飾符
。成員修飾符
。存取修飾符

5.5.1 類修飾符
    到目前為止,我還沒有涉及到類修飾符,而只涉及到了應用于類的存取修飾符。但是,有兩個修飾符你可以用于類:
    abstract——關于抽象類的重要一點就是它不能被實例化。只有不是抽象的派生類才能被實例化。派生類必須實現抽
象基類的所有抽象成員。你不能給抽象類使用sealed 修飾符。
     sealed——密封 類不能被繼承。使用該修飾符防止意外的繼承,在.NET框架中的類用到這個修飾符。
    要見到兩個修飾符的運用,看看清單5.12 ,它創建了一個基于一個抽象類的密封類(肯定是一個十分極端的例子)。

清單  5.12  抽象類和密封類

1: using System;
2:
3: abstract class AbstractClass
4: {
5:  abstract public void MyMethod();
6: }
7:
8: sealed class DerivedClass:AbstractClass
9: {
10:  public override void MyMethod()
11:  {
12:   Console.WriteLine("sealed class");
13:  }
14: }
15:
16: public class TestApp
17: {
18:  public static void Main()
19:  {
20:   DerivedClass dc = new DerivedClass();
21:   dc.MyMethod();
22:  }
23: }

5.5.2  成員修飾符
    與有用的成員修飾符的數量相比,類修飾符的數量很少。我已經提到了一些,這本書即將出現的例子描述了其它的成
員修飾符。
    以下是有用的成員修飾符:
        abstract——說明一個方法或存取標志不能含有一個實現。它們都是隱式虛擬,且在繼承類中,你必須提供
override關鍵字。
     const——這個修飾符應用于域成員或局部變量。在編譯時常量表達式被求值,所以,它不能包含變量的引用。
    event ——定義一個域成員或屬性作為類型事件。用于捆綁客戶代碼到類的事件。
    extern——告訴編譯器方法實際上由外部實現。第10章 “和非受管代碼互相操作” 將全面地涉及到外部代碼。
    override——用于改寫任何基類中被定義為virtual的方法和存取標志。要改寫的名字和基類的方法必須一致。
    readonly——一個使用  readonly修飾符的域成員只能在它的聲明或者在包含它的類的構造函數中被更改。

    static——被聲明為static的成員屬于類,而不屬于類的實例。你可以用static 于域成員、方法、屬性、操作符甚至
構造函數。
    virtual——說明方法或存取標志可以被繼承類改寫。

5.5.3  存取修飾符
    存取修飾符定義了某些代碼對類成員(如方法和屬性)的存取等級。你必須給每個成員加上所希望的存取修飾符,否
則,默認的存取類型是隱含的。
    你可以應用4個 存取修飾符之一:
    public——任何地方都可以訪問該成員,這是具有最少限制的存取修飾符。
    protected——在類及所有的派生類中可以訪問該成員,不允許外部訪問。
    private——僅僅在同一個類的內部才能訪問該成員。甚至派生類都不能訪問它。
    internal——允許相同組件(應用程序或庫)的所有代碼訪問。在.NET組件級別,你可以把它視為public,而在外部
則為private。
    為了演示存取修飾符的用法,我稍微修改了Triangle例子,使它包含了新增的域成員和一個新的派生類(見清單
5.13)。

清單 5.13  在類中使用存取修飾符

1: using System;
2:
3: internal class Triangle
4: {
5:  protected int m_a, m_b, m_c;
6:  public Triangle(int a, int b, int c)
7:  {
8:   m_a = a;
9:   m_b = b;
10:   m_c = c;
11:  }
12:
13:  public virtual double Area()
14:  {
15:   // Heronian formula
16:   double s = (m_a + m_b + m_c) / 2.0;
17:   double dArea = Math.Sqrt(s*(s-m_a)*(s-m_b)*(s-m_c));
18:   return dArea;
19:  }
20: }
21:
22: internal class Prism:Triangle
23: {
24:  private int m_h;
25:  public Prism(int a, int b, int c, int h):base(a,b,c)
26:  {
27:   m_h = h;
28:  }
29:
30:  public override double Area()
31:  {
32:   double dArea = base.Area() * 2.0;
33:   dArea += m_a*m_h + m_b*m_h + m_c*m_h;
34:   return dArea;
35:  }
36: }
37:
38: class PrismApp
39: {
40:  public static void Main()
41:  {
42:   Prism prism = new Prism(2,5,6,1);
43:   Console.WriteLine(prism.Area());
44:  }
45: }

        Triangle 類和 Prism 類現在被標為 internal。這意味著它們只能在當前組件中被訪問。請記住“.NET組件”這
個術語指的是包裝( packaging,),而不是你可能在COM+中用到的組件。Triangle 類有三個 protected成員,它們在構
造函數中被初始化,并用于面積計算的方法中。由于這些成員是protected 成員,所以我可以在派生類Prism中訪問它們,
在那里執行不同的面積計算。Prism自己新增了一個成員m_h,它是私有的——甚至派生類也不能訪問它。
      花些時間為每個類成員甚至每個類計劃一種保護層次,通常是個好主意。當需要引入修改時,全面的計劃最終會幫
助你,因為沒有程序員會愿意使用“沒有文檔”的類功能。
5.6  小結
    這章顯示了類的各種要素,它是運行實例(對象)的模板。在一個對象的生命期,首先被執行的代碼是個構造函數。
構造函數用來初始化變量,這些變量后來在方法中用于計算結果。
    方法允許你傳遞值、引用給變量,或者只傳送一個輸出值。方法可以被改寫以實現新的功能,或者你可以屏蔽基類成
員,如果它實現了一個具有和派生類成員相同名字的方法。
    命名屬性可以被當作域成員(成員變量)或屬性存取標志實現。后者是get和set存取標志,忽略一個或另外一個,你
可以創建僅寫或僅讀屬性。存取標志非常適合于確認賦給屬性的值。
    C#類的另外一個功能是索引,它使象數組語法一樣訪問類中值成為可能。還有,如果當類中的某些事情發生時,你想
客戶得到通知,要讓它們與事件關聯。
    當垃圾收集器調用析構函數時,對象的生命就結束了。由于你不能準確地預測這種情況什么時候會發生,所以應該創
建一個方法以釋放這些寶貴的資源,當你停止使用它們時。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美亚洲视频在线观看| 欧美疯狂做受xxxx高潮| 国产精品高潮呻吟久久av黑人| 一夜七次郎国产精品亚洲| 日韩美女av在线免费观看| 欧美精品激情在线| 欧美国产日韩一区二区| 国产69精品99久久久久久宅男| 欧美日韩国产中文字幕| 中日韩午夜理伦电影免费| 亚洲第一页自拍| 亚洲精品有码在线| 中文字幕日韩欧美精品在线观看| 2020久久国产精品| 国内精品400部情侣激情| 国产视频精品一区二区三区| 欧美第一黄色网| www高清在线视频日韩欧美| 欧美日韩在线视频观看| 夜夜嗨av色综合久久久综合网| 亚洲高清福利视频| 日韩女优在线播放| 亚洲欧美一区二区三区久久| 蜜月aⅴ免费一区二区三区| 在线成人一区二区| 欧美精品福利在线| 亚洲精品福利免费在线观看| 欧洲美女7788成人免费视频| 日韩视频在线免费| 欧美日韩中文字幕综合视频| 亚洲自拍高清视频网站| 91在线播放国产| 国产99久久精品一区二区 夜夜躁日日躁| 日韩av快播网址| 日韩高清av在线| 日韩精品视频观看| 91久久精品国产91性色| 法国裸体一区二区| 久久精品国产久精国产思思| 国产欧美日韩中文| 欧美电影在线免费观看网站| 欧美极品少妇xxxxⅹ裸体艺术| 欧美日本国产在线| 日韩一区二区三区在线播放| 国产日韩精品在线| 日韩成人激情在线| 中文字幕欧美日韩在线| 久久免费国产视频| 国产精品欧美日韩一区二区| 国产在线观看91精品一区| 欧美日韩国产精品一区| 色伦专区97中文字幕| 国内精品伊人久久| 成人av在线天堂| 97视频在线观看视频免费视频| 亚洲精品中文字幕女同| 成人免费高清完整版在线观看| 国内免费久久久久久久久久久| 欧美性做爰毛片| 自拍偷拍亚洲一区| 精品久久久久久久中文字幕| 欧美在线观看网址综合| 亚洲激情在线观看视频免费| 成人免费xxxxx在线观看| 亚洲国产精品美女| 精品中文字幕久久久久久| 欧美国产在线视频| 国产91精品最新在线播放| 一区二区福利视频| 成人性生交大片免费观看嘿嘿视频| 国产精品高精视频免费| 欧美成人一二三| 国产成人一区二区| 国产亚洲福利一区| 亚洲人成网站色ww在线| 久久精品99久久香蕉国产色戒| 最近2019中文字幕一页二页| 日韩精品免费综合视频在线播放| 国产精品自拍视频| 91在线高清免费观看| 亚洲一区www| 欧美丝袜一区二区三区| 欧美极品少妇xxxxⅹ喷水| 日韩精品视频三区| 久久99久久亚洲国产| 久久久在线免费观看| 91欧美精品成人综合在线观看| 一区二区三区黄色| 97婷婷大伊香蕉精品视频| 中文字幕在线看视频国产欧美| 欧美美最猛性xxxxxx| 97国产精品视频人人做人人爱| 国产玖玖精品视频| 久久人人97超碰精品888| 色小说视频一区| 色综合色综合网色综合| 午夜欧美不卡精品aaaaa| 日韩精品一区二区视频| 国产一区二区三区视频在线观看| 日本高清视频一区| 亚洲性生活视频| 69av成年福利视频| 国产精品91视频| 久久精品中文字幕| 久久在线视频在线| 日韩视频免费观看| 亚洲一区二区日本| 91亚洲va在线va天堂va国| 国产精品揄拍一区二区| 96国产粉嫩美女| 亚洲社区在线观看| 黄色成人在线播放| 久久全国免费视频| 国产999在线观看| 久久久999成人| 成人免费视频在线观看超级碰| 久久精品免费播放| 夜夜躁日日躁狠狠久久88av| 精品调教chinesegay| 国产精品wwwwww| 欧美日韩亚洲高清| 91精品免费视频| 性欧美办公室18xxxxhd| 亚洲欧美综合精品久久成人| 亚洲日韩欧美视频| 久久影视三级福利片| 精品日韩美女的视频高清| 2020国产精品视频| 国产精品久久久久久久久久三级| 97视频在线观看成人| 欧美黑人巨大xxx极品| 久久国产精品偷| 欧美另类交人妖| 亚洲一区免费网站| 国产精品嫩草影院久久久| 亚洲欧美另类中文字幕| 国产91露脸中文字幕在线| 欧美精品video| 欧美在线性爱视频| 在线视频中文亚洲| 91日本在线视频| 在线观看日韩www视频免费| 久久婷婷国产麻豆91天堂| 国产91成人在在线播放| 欧美极品少妇xxxxⅹ喷水| 亚洲第一中文字幕在线观看| 欧美午夜精品久久久久久浪潮| 欧美日韩一区二区三区在线免费观看| 国产亚洲视频中文字幕视频| 亚洲精品久久久久久久久久久| 久久久最新网址| 中文字幕日韩av综合精品| 欧美日韩一区二区三区在线免费观看| 78色国产精品| 亚洲奶大毛多的老太婆| 国产精品久久久久久久久久99| 91精品国产综合久久香蕉922| 社区色欧美激情 | 亚洲国产小视频在线观看| 精品视频—区二区三区免费| 欧洲日本亚洲国产区| 亚洲国产欧美日韩精品| 日韩欧美大尺度| 欧美性一区二区三区|