深入淺出C#(中文版 圖文皆譯)第六章
《深入淺出C#(中文版 圖文皆譯)第六章》由會員分享,可在線閱讀,更多相關(guān)《深入淺出C#(中文版 圖文皆譯)第六章(48頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、 有時你真的想要像你的父母。 曾經(jīng)遇到過可以做你想要它做的事情的對象嗎?曾經(jīng)希望過你只要只要修改一點(diǎn)東西對象就變得完美了嗎?這就是C#語言中繼承如此重要的原因。讀了這一章,你將學(xué)會如何通過繼承一個對象來獲得它的行為,同時還保持修改它的行為的靈活性。你將不用再復(fù)制代碼,可以更好的模擬現(xiàn)實(shí)世界,最后寫出容易維護(hù)的代碼。 (下載源碼就到源碼網(wǎng):) 凱瑟琳也承接生日聚會 你的程序已經(jīng)可以工作了,凱瑟琳總是在用它。但是她不只是承晚宴聚會--她現(xiàn)在也做生日聚會,而且計費(fèi)方式與晚宴聚會有所不同。她需要你給程序添加生日聚會的功能。 我們需要一個BirthDayP
2、arty類 修改你的程序來計算生日聚會的花費(fèi)就意味著要添加一個類并改變窗體來同時掌管兩種類型的聚會。 一、 創(chuàng)建一個新的BirthDayParty類 這個類要計算花費(fèi),處理裝飾,并檢查蛋糕上的字體的大小。 二、 添加一個TabControl控件到窗體上。 窗體上的每一個tab就像第三章上顯示Joe和Bob有多少現(xiàn)金的GroupBox控件。點(diǎn)擊你想要顯示的tab,并向其中拖拽控件。 三、 把晚宴聚會需要的控件拖拽到第一個tab上去 要把每一個處理晚宴聚會的空間都拖拽到上面去。它們將會像原來一樣的工作,
3、但是它們只有在晚宴聚會的tab被選中時才顯示出來。 四、 向第二個tab上添加新的生日聚會的控件 你需要像設(shè)計晚宴聚會的界面一樣的來設(shè)計生日聚會的界面。 五、 根據(jù)控件來寫生日聚會的類 現(xiàn)在只需要在窗體的字段里面添加一個BirthDayParty的引用,并向新的控件添加代碼以使得它們可以使用類的方法和屬性。 問:為什么不可以像Mike想要在導(dǎo)航器中比較三條道路時一樣,直接創(chuàng)建一個DinnerParty的新實(shí)例呢? 答:因?yàn)槿绻銊?chuàng)建了DinnerParty的另一個新實(shí)例,它只能用來計劃另一個晚宴聚會。兩個同類的實(shí)例只有在你
4、需要處理同類的兩份數(shù)據(jù)的時候才會顯得有用。但是如果你需要存儲不同的數(shù)據(jù),那你就需要不同的類來完成。 問:我怎么知道該往新類里面寫些什么呢? 答:開始構(gòu)建愛一個類之前,需要先知道它是用來解決什么問題的。因此你必須和凱瑟琳談?wù)劇撬褂眠@個程序。還好你記了不少筆記!你可以通過考慮類的行為(類需要做什么)和狀態(tài)(類需要知悉什么)來想出類的方法,字段,和屬性。 四.構(gòu)建生日聚會的界面 生日聚會的GUI含有一個NumbericUpDown控件來代表人數(shù),含有一個CheckBox控件來代表高級裝飾,一個有著3D邊界的標(biāo)簽來顯示總花費(fèi)。然后還有一個TextBox控件來顯示蛋糕上要寫的字。
5、 五.你將需要這個屬性 這是BirthDayParty.CakeWriting屬性的代碼--它會派上用場的: 六.把它們組合起來 所有的部分都寫好了,現(xiàn)在只需要寫一些代碼來讓控件工作。 *添加一個BirthDayParty對象到窗體。確保你實(shí)例化了它。 *編寫NumbericUpDown控件的事件處理方法,該方法用來設(shè)置NumberOfPeople屬性。 *讓高級裝飾的CheckBox可以工作 *添加一個DisplayBirthDayPartyCost()方法,并在所有的事件處理方法中調(diào)用它,這樣顯示花費(fèi)的標(biāo)簽將會在任何變化發(fā)生的時候得以更新。 七.運(yùn)行 確保程序以
6、它被預(yù)期的方式運(yùn)行。檢查一下文字過長的時候是不是會彈出錯誤提示框。確保價錢總是正確的。上面這些做好了,你的工作就搞定了! 向凱瑟琳的聚會計劃程序添加生日聚會 給凱瑟琳的聚會計劃程序添加生日聚會 括號對于單行的代碼塊來說是可選的 很多時候你的if語句或者while循環(huán)下面的代碼塊中都會只有一句語句。如果有很多這樣的if和while,也就會有很多的括號--它看起來很不順眼!C#允許你在代碼塊中只有一句語句的情況下省略掉括號,這樣就解決了問題。所以下面的代碼絕對符合語法: 另一件事兒...你可以給超過12人的聚會額外收費(fèi)$100嗎? 用了
7、你的程序,凱瑟琳接到了很多的用戶,她可以跟某些大客戶多收一點(diǎn)費(fèi)用了。那,要怎么做才能讓你的程序有多收費(fèi)一點(diǎn)的功能呢? *修改DinnerParty.CalculateCost()方法來讓它檢查NumberOfPeople,如果人數(shù)多于12,就給返回值加上$100。 *用同樣的方式修改BirthDayParty.CalculateCost()方法。 想一下怎么能夠一下子就讓DinnerParty和BirthDayParty同時具有多收費(fèi)的功能呢。要寫設(shè)么代碼?寫在哪兒呢? 這個問題很簡單...但是如果有三個類似的類呢?四個呢?十多個呢?如果你還要維護(hù)這些類,有可能要做更多的更
8、改呢?如果要對五六個相似的類做同樣的更改需要怎么做呢? 對!在多個類中寫同樣的代碼是低效率的,而且容易出錯。 很幸運(yùn),C#給我們構(gòu)建相互關(guān)聯(lián)的、有共同行為的類提供了更好的方法:繼承。 給你的類應(yīng)用繼承,你的代碼就只需要寫一次了 DinnerParty和BirthDayParty兩個類中有很多相似代碼并不是巧合。用C#寫程序的時候,總是會創(chuàng)建代表現(xiàn)實(shí)事物的類--而現(xiàn)實(shí)中的事物總是相關(guān)聯(lián)的。你的類中有相似代碼是因?yàn)樗鼈兇淼默F(xiàn)實(shí)事物--生日聚會和晚宴聚會--有著相似的行為。 晚宴聚會和生日聚會都是聚會 如果有兩個類都是某種概括性事物的特例,你可以讓它們都
9、去繼承同一個類。這樣,它們就都是同一個基類的子類。 從概括到具體的構(gòu)建你的類模型 C#程序使用繼承,因?yàn)樗M你要構(gòu)建的現(xiàn)實(shí)事物之間的關(guān)系?,F(xiàn)實(shí)事物總是處于由概括到具體的層級中,你的程序也有自己的類層級。你的類模型中,下面層級中的類繼承于上面層級中的類。(下載源碼就到源碼網(wǎng):) 繼承,動詞 從祖先或者父母那兒取得一種特性。她想讓孩子繼承自己的褐色大眼睛,而不是她丈夫的藍(lán)色小圓眼。 你會怎樣設(shè)計動物園模擬器呢? 獅子、老虎、熊...哈哈!還有河馬、狼,或許還有貓。你要設(shè)計一個動物園模擬程序。(別太興奮了--我們不是真的要去寫代碼,只是設(shè)計動物們的類。) 我們有一
10、個要寫到程序里面去的動物的列表,但是并不全。我們知道每個動物都需要有一個對象代表,對象將會在模擬器中移動,做它被預(yù)先編程的事情。 更重要的是,我們的程序要讓別的程序員容易維護(hù),也就是說別的程序員將要能夠在需要添加新動物到模擬器的時候就能夠添加新的類進(jìn)去。 第一步做什么呢?嗯,先不說具體的某種動物,先弄清楚各種動物有什么共同的特性,所有動物的抽象的特性。然后構(gòu)建一個所有動物類都可以繼承的,有著這些特性的類。 ①找出所有動物的共同特性 看看這六個動物。獅子、河馬、老虎、貓、達(dá)爾馬西亞狗,它們有什么共同點(diǎn)呢?它們有什么聯(lián)系?你要弄清楚它們的關(guān)系然后才能構(gòu)建出包含所有特性的類模
11、型。 使用繼承來防止子類中的冗余代碼 你已經(jīng)知道了冗余代碼很糟糕。它難以維護(hù),很是讓人頭疼。我們來選擇要寫在Animal類中的只需要寫一次的字段和方法,這樣每一個動物的子類都可以從其中繼承。我們從公有字段開始吧: *Picture:可以放進(jìn)PictureBox控件的圖像。 *Food:該種動物要吃的食物種類?,F(xiàn)在,只有兩種食物類型值:肉或者草。 *Hunger:一個代表饑餓程度的int。它的改變?nèi)Q于動物什么時候進(jìn)食了和吃了多少。 *Boundaries:存儲籠子高度、寬度、位置的類的一個應(yīng)用。動物會在這個籠子中轉(zhuǎn)悠。 *Location:動物所在地的X、Y坐標(biāo)。
12、 Animal類還有四個方法可以供子類繼承: *MakeNoise():讓動物發(fā)聲的方法。 *Eat();動物吃它喜愛的食物的行為。 *Sleep();讓動物躺下并小睡的方法。 *Roam():動物喜歡在籠子里面轉(zhuǎn)悠。 ②創(chuàng)建一個基類來給動物們提供共同的特性 基類中的字段、屬性、和方法將會給所有繼承自它的子類們共同的狀態(tài)和行為。子類們都是動物,所以基類叫做Animal是說的通的。 不同的動物出聲也不同 獅吼、犬吠,據(jù)我們所知河馬不出聲。每一個Animal的子類都有一個MakeNoise()方法,但是它們的工作方式不同,代碼也不同。當(dāng)一個子類要改變繼承來的某
13、個行為的時候,這就叫做覆蓋方法。(下載源碼就到源碼網(wǎng):) ③搞明白每個Animal子類是怎樣不同的實(shí)現(xiàn)基類的行為--或者根本不實(shí)現(xiàn) 每種動物都做什么別的動物不做的事兒呢?狗吃狗糧,所以狗的Eat()方法需要覆蓋Aniaml.Eat()方法。河馬會游泳,所以河馬會有一個基類中根本不存在的Swim()方法。 想想要覆蓋什么 子類改變繼承來的行為就叫做覆蓋。每個都需要進(jìn)食。狗吃少量的肉,河馬吃大量的草。那么它們的行為的代碼是什么樣的呢?狗和河馬都要覆蓋Eat()方法。河馬的方法每次被調(diào)用將會消耗,大概,二十磅干草。狗的Eat()方法將會消耗動物園的食品供給中的十二盎司狗糧。
14、 想一想怎么給動物們分組 Aged Vermount奶酪是一種奶酪,奶酪是一種乳制品,乳制品是一種食物,一個好的類模型要可以表現(xiàn)出這點(diǎn)來。很幸運(yùn),C#給我們一種簡單的方式來實(shí)現(xiàn)這一點(diǎn)。你可以創(chuàng)建一系列互相繼承的類,自頂向下的繼承。你可以有一個Food類,它有一個子類叫做DairyProduct,而DairyProduct又是Cheese的基類,Cheese又有一個叫做Cheddar的子類,AgedVermountCheddar就是繼承自Cheddar。 ④尋找有很多共同點(diǎn)的類 狼和狗是不是看起來很相似?它們都是犬科動物,去看看它們的行為,肯定有很多的共同點(diǎn)。它們有
15、可能吃一樣的食物,睡覺的方式也相似。家貓,獅子和老虎又怎么樣呢?事實(shí)是它們都以相同的方式繞著自己的棲息地轉(zhuǎn)悠。在Animal和這三個貓科動物的類之間有一個Feline(貓科動物)類肯定會對于避免冗余代碼有幫助。 創(chuàng)建類層次結(jié)構(gòu) 創(chuàng)建很多類,最上面有一個基類,下面是子類,子類們還有自己的子類,這樣就是創(chuàng)建了類層次結(jié)構(gòu)。這不僅可以防止冗余代碼,也是一個很明智的層次結(jié)構(gòu)。但是最大的好處就是這可以讓你的代碼易懂,且容易維護(hù)??磩游飯@模擬器的時候,如果看到Feline類中定義了一些屬性和方法,你就可以立即意識到你看見的是所有貓科動物共享的東西。你的類層次結(jié)構(gòu)就像幫你游歷代碼的地圖。
16、 ⑤完成你的類層次結(jié)構(gòu) 現(xiàn)在你知道了如何組織動物類,你可以添加Feline和Canine類了。 每個子類都擴(kuò)展它的基類 你并不會被局限于一個子類繼承來的方法...你已經(jīng)知道這一點(diǎn)了!畢竟你已經(jīng)自己構(gòu)建類很久了。向一個類添加繼承就是把已經(jīng)創(chuàng)建好的類拿過來,并通過添加屬性,字段,方法來擴(kuò)展它。所以如果你要給狗添加一個Fetch()方法,這是很普通的。這不會繼承或者覆蓋任何東西--只有狗才有這個方法,河馬,狼,犬科動物,動物等等類都不會得到這個方法。 C#總是會調(diào)用最具體的方法 如果你讓狗對象轉(zhuǎn)悠(Roam()方法),只有一個方法可以做到--就是Animal中的版本。那
17、要是要讓狗出聲音呢?調(diào)用的是哪個MakeNoise()方法呢?要搞明白這一點(diǎn)并不難。Dog類中的方法告訴你狗是怎么做這件事兒的。如果這個方法是在Canine中的話,那就是告訴你所有的犬科動物都是這樣做這件事兒的。如果它在Animal中的話,那就是描述了一個普遍性的、對于所有動物都適用的行為。所以如果你讓狗出聲音的話,C#會先去Dog類中找適用于狗的這種行為。如果Dog類沒有這種行為,就去Canine中找,然后再去Animal中找。 繼承基類要用冒號 寫一個類的時候,繼承另一個類要用冒號(:)。冒號前面的就是子類,它會得到父類所有的字段,屬性,方法。 子類繼承基類的時候,基類所有的字段
18、,屬性,方法會自動的添加進(jìn)子類中去。 問:為什么子類和父類之間的箭頭指向父類?如果箭頭向下指的話,這個類圖不是會好看一點(diǎn)嗎? 答:是會好看一點(diǎn),但是就不如之前準(zhǔn)確了。一個類繼承另一個類的時候,這種關(guān)系是體現(xiàn)在子類中的,父類是保持不變的。從父類的角度考慮,這樣是有道理的,給一個類添加一個子類,父類的行為是不會改變的。父類甚至到不會知曉有一個新的子類存在。父類的方法,字段,和屬性都是原封不動的。而子類的行為卻改變了。每一個子類的實(shí)例都會得到父類所有的字段,方法和屬性,而這一切,只寫一個冒號就做到了。在類圖上這樣畫箭頭就代表父類會成為子類的一部分,而箭頭指向子類繼承的父類。 看
19、看這些類模型和聲明,然后圈出錯誤的語句。 看看這些類模型和聲明,然后圈出錯誤的語句。 我們知道繼承會把基類的屬性,方法,字段添加到子類中去 如果子類需要父類所有的字段,方法,屬性的話,繼承是很簡單的。 ...但是有的鳥不會飛! 如果父類有一個在子類中需要被改變的方法,那怎么辦呢? 子類可以通過覆蓋來改變或者替換繼承來的方法 有時候你會想要讓子類繼承父類的大部分行為,而不是全部。你可以用繼承改變一個類繼承來的方法。 ①給父類中的方法添加virtual關(guān)鍵字 子類可以覆蓋在父類中用virtual關(guān)鍵字標(biāo)記的方法,vi
20、rtual關(guān)鍵字標(biāo)記的方法表示可以被子類覆蓋。 ②給子類添加一個同名的方法 需要用相同的方法簽名--也就是說相同的返回值和參數(shù)--而且還需要在聲明中用override關(guān)鍵字。 在子類中用以override關(guān)鍵字修飾的方法來替代從父類中繼承來的方法。在此之前,父類中的方法需要用virtual關(guān)鍵字修飾。 可以使用父類的地方,都可以用子類來替代父類 繼承最有用的方面就是可用子類來替代父類。所以,如果Recipe()方法接受一個Cheese類型的參數(shù),而有一個叫做AgedVermontCheddar的類繼承自Cheese,你可以把AgedVermontCheddar
21、的實(shí)例傳進(jìn)該方法作為參數(shù)。Recipe()方法只可以訪問Cheese中定義的屬性,方法,字段,它不可以訪問AgedVermontCheddar中的獨(dú)有的成員。 ①假設(shè)我們有一個分析三明治對象的方法 ②你可以給上面的方法傳遞一個三明治對象--不過你也可以傳遞一個BLT對象,因?yàn)槲覀冏孊LT繼承了Sandwich類,BLT也是一種三明治了。 ③類圖可以向下看--也就是說父類的引用變量可以被賦值為子類的實(shí)例。而反之則不然。 簡介: 1. 填寫代碼中的空白處 2. 讓填進(jìn)去的候選代碼和輸出相匹配 下面是一段C#程序。代碼中遺失了一塊!你要把候選的代
22、碼塊(左側(cè)列出的那些)和相應(yīng)的輸出聯(lián)系起來,也就是說填入哪段代碼塊將要在消息框中彈出哪段輸出呢?并不是所有的輸出都要用到,而且有的輸出不止要用一次。畫線把候選代碼塊和輸出結(jié)果連起來。 (不要把它寫進(jìn)IDE去試--在紙上做出它來,你會學(xué)到更多?。? 泳池難題 你的任務(wù)是把游泳池中的代碼片段拿出來填進(jìn)代碼中的空白處??梢远啻问褂猛粋€代碼塊,也有的代碼塊可能不會用到。你的目標(biāo)就是讓這些類可以編譯并以運(yùn)行。別被表面現(xiàn)象騙了--這個難題比它看起來要難。 問:你在泳池難題中指出了程序入口點(diǎn)--這是不是意味著我可以寫一個沒有Form1窗體的程序? 答:對。創(chuàng)建窗體應(yīng)
23、用的時候,IDE會幫你創(chuàng)建項(xiàng)目需要的所有文件,這包括一個Program.cs(內(nèi)有一個含有程序入口點(diǎn)的靜態(tài)類),還有Form1.cs(內(nèi)含一個叫做Form1的空白窗體)。 試試這樣做:用IDE創(chuàng)建新項(xiàng)目的時候不要選擇窗體項(xiàng)目,選擇空項(xiàng)目。然后向其中添加一個類文件,把泳池難題中的代碼寫進(jìn)去。由于這個程序要用消息框,你需要通過添加引用來引入“System.Windows.Forms”(而創(chuàng)建窗體應(yīng)用的時候,這一個步驟將會有IDE幫你自動完成)。最后,在項(xiàng)目菜單中選擇屬性,并把項(xiàng)目類型設(shè)置為窗體應(yīng)用。 現(xiàn)在運(yùn)行...你就可以看見結(jié)果了!恭喜,你徒手創(chuàng)建了一個C#程序。 問:可以繼承含有入口
24、點(diǎn)的類嗎? 答:可以。入口點(diǎn)必須是靜態(tài)方法,但是它并不一定要處于一個靜態(tài)類中。(記住,用static修飾的類不可以被實(shí)例化,但是它的方法在程序一開始就可用了。所以在泳池難題的程序中,你可以在任何其他方法中調(diào)用TestBoats.Main(),而無須聲明引用變量或者用new關(guān)鍵字實(shí)例化對象。) 問:我搞不明白為什么有些方法叫做“虛方法”--它們看起來很真實(shí)感?。? 答:virtual關(guān)鍵字關(guān)系到.Net在后臺如何處理虛方法。.net會使用一種叫做虛方法表的東西。.NET用它記錄哪些方法是虛方法,哪些方法被覆寫過。別擔(dān)心--你無需知道它具體怎么工作也可以使用虛方法! 問:你說類圖中只可以向上
25、移不可以向下移是什么意思? 答:在類圖中,上層的類比下層的類更具抽象性。比較具體的類(例如襯衫,汽車)繼承自比較抽象的類(例如衣物,機(jī)動車)。這樣想,就很容易明白當(dāng)你只是需要隨便一種機(jī)動車的時候汽車,小貨車,摩托車都可以勝任。但是如果你需要汽車,摩托車對你就沒有用了。 繼承就如上面說的那樣。如果有一個方法,接受Vehicle類型的參數(shù),而Motorcycle繼承自Vehicle,這樣你就可以把一個Motorcycle的實(shí)例傳進(jìn)這個方法中去。但是如果接受的參數(shù)是Motorcycle類型,就不是隨便傳進(jìn)一個Vehicle類型去都行了,因?yàn)閭鬟M(jìn)去的有可能是Van(小貨車)的實(shí)例,而這樣如果該方法
26、要訪問Hadlebars(摩托車把)屬性的話,C#就不知道怎么辦好了! 對于需要一個父類類 型作參數(shù)的方法,可 以傳遞一個子類的實(shí) 例進(jìn)去。 子類可以通過使用base關(guān)鍵字訪問基類 即使你已經(jīng)覆寫了父類的方法、屬性,但是有時你還是會需要訪問父類。很幸運(yùn),我們可以用base關(guān)鍵字來訪問父類的任何方法。 ①所有動物都要吃東西,所以Animal類有一個Eat()方法,它接受一個Food對象作為參數(shù)。 ②變色龍用舌頭捕食。所以Chameleon(變色龍)類會繼承Animal類并覆寫Eat()。 ③無需寫重復(fù)的代碼,我們只需使用base關(guān)鍵字來調(diào)用已經(jīng)被覆蓋的方法。我們現(xiàn)在
27、對舊的和新版本的Eat()方法都有訪問權(quán)。 父類有構(gòu)造方法,子類也要有 一個類由構(gòu)造方法,那么任何繼承自它的子類都會調(diào)用它的構(gòu)造方法。子類和父類的構(gòu)造方法可以有不同的參數(shù)列表。 父類的構(gòu)造方法首先得以調(diào)用,然后才執(zhí)行子類的構(gòu)造方法 但是別盲目相信我們說的--自己試試看! ①創(chuàng)建一個父類,讓它的構(gòu)造方法彈出一個消息框 然后向窗體添加一個按鈕,它實(shí)例化父類并會彈出消息框: ②寫一個子類,但是別調(diào)用父類的構(gòu)造方法 然后向窗體添加一個按鈕,讓它實(shí)例化一個子類的對象并顯示一個消息框: ③通過讓子類的構(gòu)造方法調(diào)用父類的構(gòu)造方法來解決問題 然后實(shí)例
28、化子類,看看消息框以什么順序彈出來! 現(xiàn)在你可以去完成凱瑟琳的任務(wù)了! 你上次放手凱瑟琳的工作的時候,剛剛給她的程序添加了生日聚會的功能。她需要你給她的程序添加一個向12人以上的聚會加收$100的功能。當(dāng)時你好像必須把一樣的代碼寫兩次,每個類一次。現(xiàn)在你會用繼承了,你可以讓兩個聚會類繼承同一個父類,父類中含有兩個聚會類的公共代碼,這樣同樣的代碼就不用寫兩次了。 如果你做的好的話,我們可以做到修改兩個類而無須修改窗體! ①我們來創(chuàng)建新的類模型 我們還是會保留DinnerParty和BirthdayParty類,但是現(xiàn)在它們要繼承自同一個Party類。我們
29、需要讓它們保持和原來一樣的方法、字段、屬性,這樣就無需修改窗體了。但是某些方法、字段、屬性需要移動到Party類中去,我們還需要覆寫它們中的一部分。 ②創(chuàng)建Party類 確保Party類是public的。你需要仔細(xì)的觀察類圖,來分析出要把DinnerParty和BirthdayParty中哪些的方法、屬性移動到Party中去。 *把NumberOfPeople和CostOfDecoration移動進(jìn)去,以此來與DinnerParty和BirthdayParty保持兼容。 *也把CalculatorCostOfDecorations()和CalculateCo
30、st()方法移動進(jìn)去。如果這些方法用到了某些私有字段,也要把該字段一起移動。(記住,子類只繼承公有字段--一旦你把私有字段移動到Party類,DinnerParty和BirthdayParty類就不能訪問該字段了。) *Party類還要有構(gòu)造方法。仔細(xì)觀察一下DinnerParty和BirthdayParty的構(gòu)造方法--它們相同的部分要移動到Party的構(gòu)造方法里面去。 *現(xiàn)在添加向超過12人的聚會加收費(fèi)$100的功能。畢竟,我們就是因此才在做這些改變的!這個特性同時屬于DinnerParty和BirthdayParty,所以它需要處于Party類中。 ③讓DinnerPa
31、rty繼承自Party 由于現(xiàn)在Party類可以做很多原來DinnerParty做的工作,所以你可以把重疊部分從DinnerParty中消除掉了,只把DinnerParty中獨(dú)有的部分保留下來。 *確保構(gòu)造方法運(yùn)行良好。它做Party的構(gòu)造方法不做的事兒嗎?如果做的話,把它保留下來,其他相同部分留給父類的構(gòu)造方法去完成。 *關(guān)于健康選擇的部分要留在DinnerParty中。 *你至少需要覆寫一個方法,因?yàn)樗鯠innerParty中以獨(dú)特的方式工作。 ④讓BirthdayParty繼承Party 對于BirthdayParty也一樣,把共性的東西移動到父類,
32、只把特性的東西保留在BirthdayParty中。 *BirthdayParty的構(gòu)造方法需要做什么Party的構(gòu)造方法沒有完成的事情嗎? *你要在BirthdayParty內(nèi)處理蛋糕花費(fèi)。它觸及到一個方法和一個屬性,你需要覆寫它們。 *沒錯,可以覆寫屬性!和覆寫方法一樣。你設(shè)置base.NumberOfPeople的值的時候,會調(diào)用這個屬性父類中的的set訪問器。使用set和get訪問器都需要用到base關(guān)鍵字。 注意--你修改了DinnerParty和BirthdayParty類,讓它們繼承Party。這樣你就可以修改總花費(fèi)的計算,加收$100了,而且根本不用改變窗體。
33、帥! 創(chuàng)建一個蜂窩管理系統(tǒng) 蜂后需要你的幫助!她的蜂窩失控了,需要你寫一個程序來管理蜂窩。蜂窩里有很多工蜂,有很多工作需要做。但是她控制不了局面了,她不知道哪個蜜蜂在做什么,她也不知道是否有足夠的蜜蜂來做需要做的工作。你要創(chuàng)建一個蜂窩管理系統(tǒng)來幫助蜂后管理工蜂。它將如此工作: ①蜂后給工蜂分配工作 工蜂需要做六種工作。有的工蜂懂得采集花蜜和制作蜂蜜,其他的會維護(hù)蜂窩、巡邏、防衛(wèi)敵人。有一些工蜂會做所有的工作。所以你需要讓蜂后可以給工蜂分配其可以勝任的工作。 ②工作分配完成之后,就要開工了。 蜂后分配完工作之后,
34、她點(diǎn)擊“Work the next shift(進(jìn)行下一個半次)”按鈕。然后程序生成一個班次報告告訴蜂后哪些蜜蜂這個班次上工了,它做了什么工作,還需要多少個班次來完成一項(xiàng)工作。 首先你要構(gòu)建基本系統(tǒng) 這個項(xiàng)目分為兩部分。第一部分你要創(chuàng)建基本系統(tǒng)來管理蜂窩。這一部分有兩個類,Queen(蜂后)和Worker(工蜂)。你要為程序創(chuàng)建窗體,并把它與這兩個類結(jié)合起來。這兩個類需要封裝良好,這樣在你去創(chuàng)建第二部分的時候它們才能易于修改。 程序含有一個Queen對象來管理工作。 *Queen用一個Worker數(shù)組來管理工蜂,看它們是否已經(jīng)有分配了的工作。這個數(shù)組是一
35、個叫做workers的Woker[]私有字段。 *窗體調(diào)用AssignWork()方法,它接受一個string參數(shù)代表需要做的工作還有一個int參數(shù)代表班次。如果找到可以做這項(xiàng)工作的工蜂,返回true,否則返回false。 *窗體上的“Work the next shift”按鈕調(diào)用WorkTheNextShift()方法,此方法告訴工蜂去工作并返回一個用來顯示的班次報告。它通知工蜂去工作一個班次,并檢查工蜂的狀態(tài)以便添加到班次報告中去。 Queen用一個Worker數(shù)組來管理工蜂,了解它們正在做什么工作。 *CurrentJob是一個只讀屬性,它告訴蜂后工蜂在做什么(
36、“巡邏”,“維護(hù)蜂窩”,等等)如果工蜂沒做事兒,將會返回一個空字符串。 *蜂后用自己的DoThisJob()方法來給工蜂分配工作。如果工蜂沒有正在做的工作,并且知道怎么做這個工作,它將會接受這個工作并返回true,否則返回false。 *調(diào)用WorkOneShift()方法的時候,工蜂去工作一個班次。工蜂記錄手頭的工作還需要做幾個班次。如果手頭工作做完了,它將會把手頭工作設(shè)置為空字符串,這樣它將可以接受下一個工作。 String.IsNullOrEmpty() 由于每一個工蜂用一個字符串存貯正在做的工作,工蜂通過檢查CurrentJob屬性來知道自己是否手頭有工作--如果它在等
37、待下一個工作的話該字符為空。C#給你提供了一個簡單的方式來完成這個功能:String.IsNullOrEmpty(CurrentJob)在字符串為空或者為null的時候返回true,否則返回false。(下載源碼就到源碼網(wǎng):) 蜂后需要你的幫助!用你學(xué)過的關(guān)于類和對象的知識來構(gòu)建一個蜂窩管理系統(tǒng)來幫助蜂后管理工蜂。 ①創(chuàng)建窗體 窗體很簡單--功能都在Queen和Worker類中完成。窗體有一個私有的Queen字段,還有兩個按鈕分別調(diào)用AssignWork()和WorkTheNextShift()方法。添加一個ComboBox控件來顯示蜜蜂的工作列表(返回前幾頁查看蜜蜂的工作有哪幾項(xiàng)),添
38、加一個NumbericUpDown控件,兩個按鈕,還有一個多行的textbox控件來顯示班次報告。你也需要一個窗體的構(gòu)造方法--就在截圖下面。 ②創(chuàng)建Worker和Queen類 你對于這兩個類需要的東西了解的已經(jīng)夠多了?,F(xiàn)在只需要一點(diǎn)細(xì)節(jié)了。Queen的AssignWork()方法遍歷工蜂數(shù)組并用工蜂的DoThisJob()方法來分配工作。工蜂用自己的jobsICando字符串?dāng)?shù)組來檢查自己是否會做分配的工作。如果會做該工作它將自己的shiftToWork私有字段設(shè)置為工作時間,設(shè)置CurrentJob為分配的工作,設(shè)置shiftNumber為零。工蜂工作一個班次之后,給shift
39、Number減一。只讀的ShiftsNumber屬性返回shiftsToWork-shiftsWorked。蜂后用它檢查一項(xiàng)工作還剩多少班次。 用繼承來擴(kuò)展蜜蜂管理系統(tǒng) 既然你已經(jīng)做成了基本系統(tǒng),用繼承來讓系統(tǒng)知道每個蜜蜂消耗多少蜂蜜。不同的蜜蜂消耗不同數(shù)量的蜂蜜,蜂后消耗的蜂蜜最多。所以現(xiàn)在你需要構(gòu)建一個Bee類來讓Queen和Worker繼承它。 還沒完工!蜂后需要知道蜂窩內(nèi)的蜂蜜消耗量。你可以在這兒好好地試用一下你學(xué)到的繼承技術(shù)! ①蜂后的會計告訴她蜂蜜的產(chǎn)量不足。蜂后需要知道蜂蜜消耗量,才可以決定是否讓工蜂由保護(hù)卵轉(zhuǎn)去生產(chǎn)蜂蜜。
40、 *密封都需要吃蜂蜜。所以它們需要生產(chǎn)更多的蜂蜜。 *工蜂工作的時候消耗的蜂蜜比較多。倒數(shù)第一班次消耗10個單位的蜂蜜,倒數(shù)第二個班次消耗11個單位,以此類推。所以用ShiftLeft加上9就可以知道該班次需要多少蜂蜜。 *蜜蜂不工作的時候消耗7.5單位的蜂蜜。 *上面只是普通的情況。如果一只蜜蜂體重超過100毫克,消耗的蜂蜜多35%,蜂后也是如此。 *蜂后消耗很多蜂蜜。蜂后監(jiān)工蜜蜂們工作的時候很勞累,所以也需要更多的蜂蜜。她消耗的蜂蜜和剩余班次最多的蜜蜂一樣多。 *蜂后需要向班次報告中添加蜂蜜消耗量。 ②創(chuàng)建一個Bee類來掌管蜂蜜計算。 蜂后和工蜂消耗蜂蜜的方式一樣,所
41、以讓它們繼承自Bee可以防止代碼冗余。蜜蜂需要知道自己的體重(這樣才可以知道是否需要給消耗量添加35%)。 *創(chuàng)建一個GetHoneyConsumption()方法,它計算工蜂消耗量。由于蜂后需要做額外的計算,所以工蜂繼承這個方法,蜂后覆寫這個方法。 *GetHoneyConsumption()方法需要知道剩余的班次。 *計算蜂蜜消耗量需要知道密封的體重,所以Bee的構(gòu)造方法需要接受一個代表體重的參數(shù),并把它存儲在一個字段里。而由于其他類并不需要訪問它,所以可以把它聲明為私有變量。 ③讓W(xué)orker類繼承Bee類 需要讓W(xué)orker的構(gòu)造方法對于父類的構(gòu)造方法。Worker的
42、構(gòu)造方法要接受一個代表體重的參數(shù)并把它傳進(jìn)父類的構(gòu)造方法里面去。然后給Worker的ShiftLeft添加override關(guān)鍵字。這樣工蜂就可以計算蜂蜜消耗量了...并沒有大幅度的修改Worker類! ④讓Queen類繼承Bee類 由于蜂后需要計算蜂蜜消耗量并向報告中寫入消耗量,所以她需要做比較多的改動。 *蜂后覆寫B(tài)ee.GetHoneyConsumption()方法,向其中添加額外的計算。蜂后需要知道是否有2個或者更少的工蜂在工作,這樣才可以知道是否需要20或者30個單位的額外蜂蜜。 *修改蜂后的WorkTheNextShift()方法來把消耗量寫入報告。最后需要向報告中寫入“總共蜂蜜消耗量:XXX單位”。 *像工蜂類一樣的修改蜂后的構(gòu)造方法。 ⑤修改窗體來初始化蜜蜂 由于修改了蜜蜂的構(gòu)造方法,所以需要修改創(chuàng)建它們的方式,多加一個代表體重的參數(shù)。 對于窗體只需要這么一點(diǎn)修改! 下面是Bee類。它完成蜂蜜消耗量的基本計算,Queen和Worker類都需要繼承這一行為。 繼承使得你可以很容易的給Queen和Worker添加蜂蜜消耗量計算的行為。如果不是有繼承要做這個改變就很困難,會產(chǎn)生很多重復(fù)代碼。
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 指向核心素養(yǎng)發(fā)展的高中生物學(xué)1輪復(fù)習(xí)備考建議
- 新課程新評價新高考導(dǎo)向下高三化學(xué)備考的新思考
- 新時代背景下化學(xué)高考備考策略及新課程標(biāo)準(zhǔn)的高中化學(xué)教學(xué)思考
- 2025屆江西省高考政治二輪復(fù)習(xí)備考建議
- 新教材新高考背景下的化學(xué)科學(xué)備考策略
- 新高考背景下的2024年高考化學(xué)二輪復(fù)習(xí)備考策略
- 2025屆高三數(shù)學(xué)二輪復(fù)習(xí)備考交流會課件
- 2025年高考化學(xué)復(fù)習(xí)研究與展望
- 2024年高考化學(xué)復(fù)習(xí)備考講座
- 2025屆高考數(shù)學(xué)二輪復(fù)習(xí)備考策略和方向
- 2024年感動中國十大人物事跡及頒獎詞
- XX教育系統(tǒng)單位述職報告教育工作概述教育成果展示面臨的挑戰(zhàn)未來規(guī)劃
- 2025《增值稅法》全文解讀學(xué)習(xí)高質(zhì)量發(fā)展的增值稅制度規(guī)范增值稅的征收和繳納
- 初中資料:400個語文優(yōu)秀作文標(biāo)題
- 初中語文考試專項(xiàng)練習(xí)題(含答案)