




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、.NET.NET面向對象程序設計面向對象程序設計第第1515章章實現屬性以訪問字段實現屬性以訪問字段本章簡介本章簡介使用屬性封裝邏輯字段使用屬性封裝邏輯字段聲明聲明get accessor聲明聲明set accessor創(chuàng)建聲明了屬性的接口創(chuàng)建聲明了屬性的接口使用結構和類實現含有屬性的接口使用結構和類實現含有屬性的接口根據字段定義自動生成屬性根據字段定義自動生成屬性用屬性來初始化對象用屬性來初始化對象15.1 使用方法來實現封裝使用方法來實現封裝 以下結構用于將屏幕上的一個位以下結構用于將屏幕上的一個位置表示成一個(置表示成一個(X,Y)坐標對)坐標對 假定假定x坐標的取值范圍是坐標的取值范圍
2、是01280,y的取值范圍是的取值范圍是01024 private static int rangeCheckedX(int x) if (x 1280) throw new ArgumentOutOfRangeException(X); return x; private static int rangeCheckedY(int y) if (y 1024) throw new ArgumentOutOfRangeException(Y); return y; struct ScreenPosition public int X; public int Y; public ScreenPos
3、ition(int x, int y) this.X = rangeCheckedX(x); this.Y = rangeCheckedY(y); 問題:違反了封裝的原則,沒有將其數據保持問題:違反了封裝的原則,沒有將其數據保持private狀態(tài)狀態(tài) 雖然雖然ScreenPosition構造器會對它的參數進行范圍構造器會對它的參數進行范圍檢查,但在創(chuàng)建好一個對象后,就可以隨便訪問檢查,但在創(chuàng)建好一個對象后,就可以隨便訪問public字段字段ScreenPosition origin = new ScreenPosition(0, 0); . int xpos = origin.X; origi
4、n.Y = -100; / oops 解決該問題的方法:將字解決該問題的方法:將字段設為段設為private,并添加一,并添加一個取值(個取值(getr accessor)方 法 和 一 個 賦 值 (方 法 和 一 個 賦 值 ( s e t accessor)方法,以便分)方法,以便分別讀取和寫入每個別讀取和寫入每個private字段的值字段的值 然后,賦值方法就可以對然后,賦值方法就可以對新的字段值執(zhí)行范圍檢查新的字段值執(zhí)行范圍檢查 缺點:它使用的是不太方缺點:它使用的是不太方便的,基于方法的語法便的,基于方法的語法uint xpos = origin.GetX(); uorigin.S
5、etX(xpos + 10);struct ScreenPosition . public int GetX() return this.x; public void SetX(int newX) this.x = rangeCheckedX(newX); . private static int rangeCheckedX(int x) . private static int rangeCheckedY(int y) . private int x, y; 15.2 什么是屬性什么是屬性 屬性(屬性(property)是字段)是字段和方法的一個交集:和方法的一個交集:它看它看起來像是一個字
6、段,行為起來像是一個字段,行為上又像一個方法上又像一個方法 訪問一個屬性所用的語法訪問一個屬性所用的語法和訪問一個字段的語法是和訪問一個字段的語法是相同的相同的 編譯器會將這種字段風格編譯器會將這種字段風格的語法自動轉換成對特定的語法自動轉換成對特定accessor方法的調用方法的調用 語法:語法:AccessModifier Type propertyName get / read accessor code set / write accessor code struct ScreenPosition private int x, y; public ScreenPosition(int
7、X, int Y) this.x = rangeCheckedX(X); this.y = rangeCheckedY(Y); public int X get return this.x; set this.x = rangeCheckedX(value); public int Y get return this.y; set this.y = rangeCheckedY(value); private static int rangeCheckedX(int x) . private static int rangeCheckedY(int y) . 注意:注意:u所有所有set acc
8、essor都用一個隱藏的、都用一個隱藏的、內建的參數來傳遞內建的參數來傳遞要寫入的數據要寫入的數據upublic字段和屬性字段和屬性大寫,大寫,private的字的字段和屬性小寫段和屬性小寫屬性為訪問對象內的實例變量及訪問另一個對象屬性為訪問對象內的實例變量及訪問另一個對象中的實例變量提供了一致性的語法。中的實例變量提供了一致性的語法。屬性與等價的存取器方法執(zhí)行速度同樣快。屬性與等價的存取器方法執(zhí)行速度同樣快。當屬性的當屬性的get語句塊和語句塊和set語句塊編譯成語句塊編譯成MSIL時,時,它們都轉換成方法。在它們都轉換成方法。在MSIL中,中,get語句塊由一語句塊由一個名字為個名字為ge
9、t_的方法表示。的方法表示。set同樣。同樣。815.2.1 使用屬性使用屬性從從ScreenPosition結構的結構的X和和Y屬性中取值:屬性中取值:uScreenPosition origin = new ScreenPosition(0, 0);uint xpos = origin.X; / calls origin.X.get uint ypos = origin.Y; / calls origin.Y.get對屬性進行賦值,編譯器自動將字段風格的代碼對屬性進行賦值,編譯器自動將字段風格的代碼轉換成對該屬性的轉換成對該屬性的set accessor的調用的調用uorigin.X =
10、40; / calls origin.X.set, with value set to 40 uorigin.Y = 100; / calls origin.Y.Set, with value set to 100可以通過可以通過static關鍵字聲明靜態(tài)屬性,訪問關鍵字聲明靜態(tài)屬性,訪問static屬性時,要附加類或者結構的名稱而不是其實例屬性時,要附加類或者結構的名稱而不是其實例的名稱作為前綴的名稱作為前綴15.2.2 只讀屬性只讀屬性 可以聲明只包含一個可以聲明只包含一個get accessor的屬性,即聲明了的屬性,即聲明了一個只讀屬性一個只讀屬性 X屬性不包含屬性不包含set acc
11、essor,所以,如下操作錯誤,所以,如下操作錯誤 origin.X = 140; / compile-time error示例:示例:struct ScreenPosition . public int X get return this.x; 15.2.3 只寫屬性只寫屬性 也可以聲明只包含一個也可以聲明只包含一個set accessor的屬性,即聲明的屬性,即聲明了一個只寫屬性了一個只寫屬性 X 屬 性 不 包 含屬 性 不 包 含 g e t accessor,所以,如下操,所以,如下操作錯誤作錯誤Console.WriteLine(origin.X); / 編譯器編譯器error o
12、rigin.X = 200; / OK origin.X += 10;/ 編譯器編譯器error示例:示例:struct ScreenPosition . public int X set this.x = rangeCheckedX(value); 只寫屬性適用于對密碼這只寫屬性適用于對密碼這樣的屬性進行保護樣的屬性進行保護15.2.4 屬性的可訪問性屬性的可訪問性可訪問性是在聲明屬性時指定的,但是,在屬性可訪問性是在聲明屬性時指定的,但是,在屬性的聲明中,可以為的聲明中,可以為get和和set單獨指定可訪問性單獨指定可訪問性struct ScreenPosition public int
13、X get return this.x; private set this.x = rangeCheckedX(value); public int Y get return this.y; private set this.y = rangeCheckedY(value); private int x, y; 注意:注意:u定義時,只能改變一個定義時,只能改變一個accessor的可訪問性的可訪問性uaccessor的訪問修飾符所指定的可訪問性在限制程度的訪問修飾符所指定的可訪問性在限制程度上必須大于屬性的可訪問性上必須大于屬性的可訪問性警告:警告:u習慣上,為屬性和習慣上,為屬性和priv
14、ate字段賦予幾乎完全相同的名字段賦予幾乎完全相同的名稱,只是首字母大小寫有別稱,只是首字母大小寫有別u但是,要小心使用但是,要小心使用class Employee private int employeeID; public int EmployeeID; get return this.EmployeeID; set this.EmployeeID = value; 15.3 理解屬性的局限性理解屬性的局限性屬性在外觀、行為和感覺上都類似于字段,但它屬性在外觀、行為和感覺上都類似于字段,但它們本質上是方法,并不是真正的字段們本質上是方法,并不是真正的字段屬性的限制:屬性的限制:u只有在一個
15、結構或類初始化好之后,才能通過這個結只有在一個結構或類初始化好之后,才能通過這個結構或類的屬性來進行賦值構或類的屬性來進行賦值ScreenPosition location; location.X = 40; / compile-time error, location not assignedu所以,定義結構和類時,一開始就應該使用屬性,而所以,定義結構和類時,一開始就應該使用屬性,而不是先用字段,后來又變成屬性,字段變成屬性后,不是先用字段,后來又變成屬性,字段變成屬性后,以前使用了這個類或結構的代碼就可能無法正常工作以前使用了這個類或結構的代碼就可能無法正常工作u不能將屬性作為一個不能將
16、屬性作為一個ref或者或者out參數值傳給一個方法;參數值傳給一個方法;但可以將一個可寫的字段作為但可以將一個可寫的字段作為ref或或out參數值傳遞,這參數值傳遞,這是因為屬性并不真正指向一個內存位置,它代表的是一是因為屬性并不真正指向一個內存位置,它代表的是一個方法個方法u在一個屬性中,最多只能包含一個在一個屬性中,最多只能包含一個get accessor和一個和一個set accessor,屬性不能包含其他方法、字段或屬性,屬性不能包含其他方法、字段或屬性uget accessor和和set accessor不能獲取任何參數,要賦不能獲取任何參數,要賦的值會通過內建的、隱藏的的值會通過內
17、建的、隱藏的value變量,自動傳給變量,自動傳給set accessoru不能聲明不能聲明const屬性屬性合理使用屬性合理使用屬性class BankAccount . public money Balance get . set . private money balance; class BankAccount . public money Balance get . public void Deposit(money amount) . public bool Withdraw(money amount) . private money balance; 15.4 在接口中聲明屬性在
18、接口中聲明屬性除了可在接口中聲明方法之外,還可以定義屬性除了可在接口中聲明方法之外,還可以定義屬性interface IScreenPosition int X get; set; int Y get; set; 實現該接口的任何類或結構都必須實現實現該接口的任何類或結構都必須實現X和和Y屬性屬性,并在屬性中定義,并在屬性中定義get和和setstruct ScreenPosition : IScreenPosition . public int X get . set . public int Y get . set . . 在類中實現接口屬性時,可以將屬性的實現聲明在類中實現接口屬性時,可
19、以將屬性的實現聲明為為virtual,以允許未來派生的類重寫這些實現,以允許未來派生的類重寫這些實現例如:例如:class ScreenPosition : IScreenPosition public virtual int X get . set . public virtual int Y get . set . 還可以選擇使用顯式接口實現語法來實現一個屬還可以選擇使用顯式接口實現語法來實現一個屬性,屬性的顯式實現是非公共和非虛的(因而不性,屬性的顯式實現是非公共和非虛的(因而不能被重寫)能被重寫)struct ScreenPosition : IScreenPosition int I
20、ScreenPosition.X get . set . int IScreenPosition.Y get . set . private int x, y; 課本課本276頁練習頁練習15.5 生成自動屬性生成自動屬性屬性的兩個主要優(yōu)勢:屬性的兩個主要優(yōu)勢:u與應用程序的兼容性與應用程序的兼容性u與接口的兼容性:如果要實現一個接口,而且接口將與接口的兼容性:如果要實現一個接口,而且接口將一個數據項定義成屬性,就必須實現這個屬性,使之一個數據項定義成屬性,就必須實現這個屬性,使之與接口中的規(guī)范相符與接口中的規(guī)范相符C#編譯器能夠自動為屬性生成代碼編譯器能夠自動為屬性生成代碼class Cir
21、cle public int Radius get; set; . 自動生成的屬性不可以是自動生成的屬性不可以是只讀或者只寫的只讀或者只寫的class Circle private int _radius; public int Radius get return this._radius; set this._radius = value; . 15.6 使用屬性來初始化對象使用屬性來初始化對象public class Triangle private int side1Length; private int side2Length; private int side3Length; pub
22、lic Triangle() this.side1Length = this.side2Length = this.side3Length = 10; public Triangle(int length1) this.side1Length = length1; this.side2Length = this.side3Length = 10; public Triangle(int length1, int length2) this.side1Length = length1; this.side2Length = length2; this.side3Length = 10; publ
23、ic Triangle(int length1, int length2, int length3) this.side1Length = length1; this.side2Length = length2; this.side3Length = length3; 可以使用命名參數,然而更好和更透明的方式是將私有變可以使用命名參數,然而更好和更透明的方式是將私有變量初始化為它們的默認值并定義屬性量初始化為它們的默認值并定義屬性public class Triangle private int side1Length = 10; private int side2Length = 10; p
24、rivate int side3Length = 10; public int Side1Length set this.side1Length = value; public int Side2Length set this.side2Length = value; public int Side3Length set this.side3Length = value; Triangle tri1 = new Triangle Side3Length = 15 ; Triangle tri2 = new Triangle Side1Length = 15, Side3Length = 20
25、; Triangle tri3 = new Triangle Side2Length = 12, Side3Length = 17 ; Triangle tri4=new TriangleSide1Length=9,Side2Length=12,Side3Length = 15 ;24應用應用:使用屬性實現延遲初始化和惰性更新使用屬性實現延遲初始化和惰性更新當一個變量很少使用而且它的初始化即浪費時間當一個變量很少使用而且它的初始化即浪費時間又浪費資源時,可使用延遲初始化技術。又浪費資源時,可使用延遲初始化技術。惰性更新(惰性更新(lazy update)25實例分析:實例分析:為農產品商人編寫
26、程序為農產品商人編寫程序要求:在合理的精度范圍內預測不同地區(qū)來年的要求:在合理的精度范圍內預測不同地區(qū)來年的產量和質量。產量和質量。相關地區(qū)相關地區(qū)10天內降水量預測是核心參數天內降水量預測是核心參數每次降水量預測要占用一定的每次降水量預測要占用一定的cpu時間時間每次計算從零開始,每每次計算從零開始,每20秒提供一個更新更準確秒提供一個更新更準確的預報的預報不同的作物有不同的種植季節(jié),所以用戶在每年不同的作物有不同的種植季節(jié),所以用戶在每年的特定時間只需預報其中的幾種,而且每次預報的特定時間只需預報其中的幾種,而且每次預報只限于幾個地區(qū)。只限于幾個地區(qū)。26程序源代碼:程序源代碼:CropF
27、orecaster.cs01: using System;02: using System.Timers;03:04: class WeatherForecaster05: 06: public static double CalculateRainfallDay10RegionA()07: 08: /Simulated complex calculations takes 5000 milliseconds09: System.Threading.Thread.Sleep(5000);10: Random randomizer = new Random();11: return (doubl
28、e)randomizer.Next(40,100);12: 13: 14: 2715: class CropForecaster16: 17: private double rainfallDay10RegionA;18: private bool rainfallDay10RegionANeedUpdate = true;19:20: public CropForecaster()21: 22: Timer aTimer = new Timer();23: aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);24: aTimer.I
29、nterval = 20000;25: aTimer.Enabled = true;26: 27:28: public double RainfallDay10RegionA29: 30: get31: 32: if (rainfallDay10RegionANeedUpdate)33: 34: rainfallDay10RegionA = WeatherForecaster.CalculateRainfallDay10RegionA();35: rainfallDay10RegionANeedUpdate = false;36: return rainfallDay10RegionA;37:
30、 38: else39: 40: return rainfallDay10RegionA;41: 42: 43: 2845: private double ComplexResultA()46: 47: /Arbitrary calculation involving lots of calls to rainfallDay10RegionA48: return (RainfallDay10RegionA / 2) + (RainfallDay10RegionA / 3) +49: (RainfallDay10RegionA / 4);50: 51:52: private double Com
31、plexResultB()53: 54: /Arbitrary calculation involving even more calls to rainfallDay10RegionA55: return (RainfallDay10RegionA / 10 - 100) + (RainfallDay10RegionA / 100);56: 57:58: public double WheatCropSizeInTonsInRegionA ()59: 60: /More arbitrary calculations returning a nice big result61: Console
32、.WriteLine(Commencing forecast calculations. Please wait.);62: return (ComplexResultA() / 2 + ComplexResultB() / 4 +63: ComplexResultA() * 100000;64: 65:66: public void OnTimedEvent(object source, ElapsedEventArgs e)67: 68: /This method is currently called automatically every 20 seconds69: Console.WriteLine(nnNew Update NeedednPerform another forecast?);70: rainfallDay10RegionANeedUpdate = true;71: 72: 2974: class ForecastTester75: 76: public static void Main()77: 78: string answer;79: CropForecaster myForecaster = n
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國非開挖工程行業(yè)需求狀況規(guī)劃研究報告
- 2025-2030年中國超級電容器行業(yè)運行態(tài)勢及發(fā)展趨勢預測報告
- 2025-2030年中國茶堿緩釋片市場發(fā)展狀況及營銷戰(zhàn)略研究報告
- 2025-2030年中國纖維素醚市場十三五規(guī)劃及發(fā)展建議分析報告
- 云南輕紡職業(yè)學院《商務談判與銷售管理》2023-2024學年第二學期期末試卷
- 廊坊師范學院《數字邏輯與數字系統(tǒng)A》2023-2024學年第二學期期末試卷
- 海南衛(wèi)生健康職業(yè)學院《圖案原理》2023-2024學年第二學期期末試卷
- 2025年陜西省安全員B證(項目經理)考試題庫
- 大連財經學院《微機原理及接口技術B》2023-2024學年第二學期期末試卷
- 湖北財稅職業(yè)學院《生物醫(yī)學檢驗儀器》2023-2024學年第二學期期末試卷
- 第一章染整工廠設計
- 上虞市化工、印染企業(yè)名單-企業(yè)負責人信息及聯系方式
- DL-T 736-2021 農村電網剩余電流動作保護器安裝運行規(guī)程
- YS/T 431-2009鋁及鋁合金彩色涂層板、帶材
- SB/T 10439-2007醬腌菜
- 與食品經營相適應的主要設備設施布局和操作流程文件
- 八年級數學下冊-全一冊-教學課件-(新版)浙教版
- 農產品電子商務培訓資料課件
- 傳熱學課后習題答案
- 酒店員工獎懲管理規(guī)章制度
- 視頻號精細化運營培訓課件
評論
0/150
提交評論