C# 學習筆記-物件導向學習 - Medium
文章推薦指數: 80 %
4. 上一課建立的Student Class 則是一種Reference Type。
宣告Reference Type 的變數時,也會先在記憶體中尋找一個空間,標記為變數名稱,然後裡面則「存放 ...
GetunlimitedaccessOpeninappHomeNotificationsListsStoriesWriteC#學習筆記-物件導向學習最近回歸寫C#後端API的職位重碰程式,買書看OOP觀念,也上網找到很讚的[小山的C#教學]影片,也看過與理解過一遍所有相關影片內容,這一篇主要筆記從[小山的C#教學-第14課]開始到[小山的C#教學-第38課]的觀看影片內容重點,方便以後的觀念複習與快速提醒與查找~一、小山的C#教學-第14課-物件導向基礎Class與小山的C#教學-第15課-Class簡介(續)物件的設計圖編寫物件的程式碼-屬性(Property)與方法(Method)建立物件與使用物件小山的重點提示重點提示1.物件導向就是要透過物件之間的互動來完成工作2.想要建立物件就必須要先定義class3.class主要分成「property屬性」、「method方法」兩個部分4.「property屬性」代表class的性質,「method方法」代表class的行為與能力5.method的格式為「publicoutput型別method名稱(input型別與名稱)」6.想要存取物件,就必須使用class的變數7.一開始宣告class的變數後不會產生任何物件,必須要用「newclass()」才能夠產生物件8.只要在變數後面加上小數點,就可以存取物件的property跟method了例如:「s.StudentID」、「s.Say()」有輸出但沒有接收輸入的Methtod:publicstringSay()有輸出也有輸入的Methtod:publicstringTalk(Students)沒有接受輸入輸出的Method:publicvoidUpgrade()小山重點提示1.如果沒有輸出值的話,就要用void代替輸出值void代表「沒有任何值」2.如果要取得輸入值的話,必須用類似宣告變數的方式宣告輸入值例如:talk這個method有兩個輸入值,字串sname與數字sgrade那就要打成p….talk(stringsname,intsgrade){定義method}3.將資料包裝成物件可以幫助重複使用資料4.將物件傳入其他物件的method中使用就是一種「物件互動」的方式二、小山的C#教學-第16課-Value與ReferenceType小山重點提示1.C#型別(Type)依照存取方式不同一共分為三種:ValueType、ReferenceType與PointerType2.C#變數裡的資料都是存放在記憶體(Memory)內的3.「int(整數)」就是一種ValueType。
它會先在記憶體中尋找一個空間,標記為變數名稱,然後將我們指定的數值存入4.上一課建立的StudentClass則是一種ReferenceType。
宣告ReferenceType的變數時,也會先在記憶體中尋找一個空間,標記為變數名稱,然後裡面則「存放物件的記憶體位置」。
5.物件必須要透過「newClass名稱()」的方式建立,沒有指向任何物件的reference(參考)變數,則存放著「null」。
6.物件都是存放在一個稱為「Heap(堆疊)」的特殊記憶體區塊三、小山的C#教學-第17課-Constructor建構子看到newStudent();,想到我們在new一個物件時,Student()是一個Method,其實也是一個建構子!!!程式可以從8行,簡化成2行!!!!!!小山重點提示1.所謂「建構子」就是一種特殊的method,它的特徵有兩個:(1)不需要設定output型別(2)method名稱與class名稱相同2.如果想要讓某個屬性的值預先設定好,可以在建構子內就指定一個數值給它3.建構子也能夠接受input(輸入值、引數),目的是要用來幫助物件做一些初始的設定4.如果建構子需要接受初始值,那必須要在建立物件時給予。
例如:Students=newStudent(10201,"小山");5.為了因應不同的情況,可以在class內撰寫多個建構子。
就算名稱相同,只要輸入值的數量與型別不同即可。
這種作法稱為Overloaded(詳情請看補充)6.如果沒有撰寫建構子,編譯器會自動幫class產生一個沒有引數的預設建構子。
7.如果自己有撰寫建構子,編譯器就不會自動幫class產生預設建構子。
補充Overloaded多載並不是只有建構子才有overloaded,只要是method都有可能會有這樣的性質。
如果今天有兩個method,這兩個method的名稱相同,但是signatures不同,那就是overloaded。
那甚麼是signature呢?signatures指的就是引數(輸入值)的種類、數目、排列與method名稱,例如下面這兩個method他們的變數名稱雖然不同,但是因為種類相同,method名稱也相同,所以signatures就算相同。
Example1:voidsleep(inttime,strings){....}voidsleep(intsleepTime,stringsound){....}而下面這兩個雖然引數數目相同,但是型別不同,所以signatures就不相同Example2:voideat(intnumberOfFood){....}voideat(stringfoodName){....}因此我們只需要辨別signatures,就可以知道method是否有重複。
重複的method是沒有意義的,因為這種情況下,程式無法得知你到底是要呼叫哪一個method。
如Ex1中,C#會當作沒看到第二個method,所以你永遠無法呼叫到它。
那你又為何要這樣寫呢?另外一個常見問題是,引數與method名稱都相同,但是output型別不同算是重複嗎?答案是,算!請看下面這個例子Example3:intrun(){...}voidrun(){...}如果我今天呼叫run()的話,你可以辨別我是要呼叫哪一個run()嗎?相信你應該了解了吧?這就是為什麼這樣也算是重複的method。
四、小山的C#教學-第18課-this變數小山重點提示1.如果程式與到出現相同變數的情況,會自動選擇比較「近」的變數「近」的意思是指Scope範圍較小但是在仍在範圍內的意思2.this是一個指向自己物件本身的ReferenceType的變數3.若將「this.」記為「這個物件的」會比較好記相關資訊連結微軟官方對於this的介紹this關鍵字-C#參考Thethis關鍵字指的是類別的目前執行個體,也用作擴充方法第一個參數的修飾詞。
thiskeywordreferstothecurrentinstanceoftheclassandisalsousedas…msdn.microsoft.com五、小山的C#教學-第19課-static修飾字StaticMethod(靜態方法),Static變數(靜態變數),StaticClass(靜態類別)小山答:是的,但是有些狀況下可以不需要,就是StaticMethod不用每次都new一個物件浪費資源,只要在方法的public與int中間,加入"static”,就不用先new出Class物件,直接能呼叫使用該Class的Method!!(如下圖所示):有StaticMethod,那~有Static變數嗎?有的!有StaticMethod,有Static變數,那~有StaticClass嗎?有的!!但是有一個小細節要注意!!!就是StaticClass無法被new出來!!小山重點提示1.使用了static修飾過的變數、method,不需要建立物件就可以直接透過class名稱使用2.static修飾過的變數是所有同class的物件共用的3.staticclass不可以用來建立物件補充static變數在記憶體內的狀態每一個物件的變數與其相關的資料都會存在物件被分配的記憶體內。
那本課提到了static變數是所有物件共用的,這個時候可能就會不禁問說:那static變數放哪裡?答案是,放在class本身所屬的記憶體區塊裡。
每個程式啟動的時候,都會分配給每個class一塊記憶體使用,裡面放的內容包含class的static變數以及class的程式碼。
當然這個部分的實作細節,會隨著不同版本的.NETFramework而有差異。
相關資訊連結微軟官方對於static的介紹VisualStudio2005RetireddocumentationPDFfilesthatcontaintheVisualStudio2005documentation.msdn.microsoft.com六、小山的C#教學-第20、21課-借還錢模擬小程式這樣就不用重複寫2次updateMoney()裡面那二行的程式碼了!!小山重點提示1.在紀錄資料的時候,可以盡量使用class包起來。
除了方便管理之外,以後需要大量增加也比較容易2.class內的「變數」可以想成「屬性」,method則可以想成「行為」3.class可以藉由constructor來強迫使用者在建立物件的時候輸入某些參數來初始化4.class內可以互相呼叫自己的method七、小山的C#教學-第22課-Array陣列[小細節]陣列其實是一種物件,System內有一個class名為Array!!string其實是一個class,所以它預設值是null盡量不要使用到編號以外的號碼小山的重點提示1.陣列通常用來存放大量類型相同的資料,如1000個整數等等2.陣列的宣告方法如下,例如要宣告可以存放40個整數的陣列,名為intArray:int[]intArray=newint[40];或是如果預先知道要存入的數值,也可以用下面的方式宣告:(假設要預先存入92,83,100)int[]intArray=newint[]{92,83,100};3.如果要存取陣列內的資料,則需要打「陣列名稱[編號]」例如要存取整數陣列scores編號3的資料:scores[3]=100;//在編號3的位置存入1004.陣列的編號是從0開始算起,因此如果陣列大小為40,則可以用的編號是0~395.陣列一開始會將每個位置的資料填上預設值,預設值則跟每一格存放的資料型別有關。
不同型別的預設值請參考「相關資訊連結」的「預設值表」6.如果使用了範圍外的編號,只有在程式執行時才會發現錯誤。
因此要特別注意7.除了int,double這些基本型別,也可以建立物件陣列。
只需要將型別名稱替換成class名稱即可,例如要宣告大小20的Studentclass的陣列可以寫:Student[]students=newStudent[20];8.陣列的大小是固定的,在宣告的時候就要決定9.陣列也是一種物件補充Class的預設值基本上,所有ValueType的變數的預設值都可以在相關連結的「預設值表」中找到。
那麼ReferenceType(指向物件的變數)的預設值又是甚麼?所有ReferenceType的預設值都是null,也就是說,如果你一開始宣告了一個變數object,然後還沒有用new來產生任何物件。
那這個object裡面存的值就是null。
因此我們在寫程式的時候,常常可以使用下列這個判斷式來比對ReferenceType的變數是否有指向任何物件。
if(object==null)//如果object沒有指向任何物件,這個判斷式就會成立另外,string其實也是一個class,所以它預設值也是null。
ValueType的陣列與ReferenceType陣列的結構在看這個條目之前,請先注意是否理解ValueType與ReferenceType這兩種變數的差別。
如果不了解的話,可以先去看「小山的C#教學-第16課-Value與ReferenceType」。
在本課的教學中,我們了解到陣列儲存整數的方法是像下面這張圖。
而我們也學過,當我們建立物件的時候,物件的本體是放在一個名為Heap(堆疊)的物件海。
然後我們物件的變數也只有紀錄物件本體的位置的而已,這些變數就稱為ReferenceType的變數。
那這些ReferenceType的陣列實際上的結構是長甚麼樣子呢?實際上,ReferenceType的陣列裡面所存的,只是一群「指向物件本體」的位址而已。
如果我們有一個classStudent,然後我們建立了Student的陣列。
再用下列的程式碼一一地建立物件,並利用陣列來儲存。
Student[]students=newStudent[20];students[0]=newStudent(10001,小山);students[1]=newStudent(10002,小羊);students[2]=newStudent(10003,元正);students[3]=newStudent(10004,高光);....那這些東西實際儲存的狀態就會像下面這張圖(箭頭代表我們可以透過位址去找到被指向的物件)動態陣列本課教學提到陣列是固定大小的,而且必須要在宣告時就決定大小。
事實上,也有不需要事先指定大小,並且可以動態改變大小的陣列。
在System.Collectioins這個namespace下有一個class叫做ArrayList。
它本身的結構與陣列很類似,但是具有自行動態調整大小的特性。
當然使用方法上會有些不同。
關於這部分的介紹有網友製作了簡單的說明,有興趣的可以點進去參考。
相關資訊連結微軟官方(MSDN)對於陣列的簡介http://msdn.microsoft.com/zh-tw/library/9b9dty7d%28v=vs.80%29.aspxMSDN的Arrayclass參考資料http://msdn.microsoft.com/en-us/library/system.array.aspxC#ValueType的預設值表http://msdn.microsoft.com/zh-tw/library/83fhsxwc%28v=vs.80%29.aspx某位網友對於ArrayList使用方法的簡單說明《[C#.NET][VB.NET]一般集合—ArrayList類別排序》http://www.dotblogs.com.tw/yc421206/archive/2009/01/21/6902.aspx八、小山的C#教學-第23課-GarbageCollection垃圾回收小山重點提示1.電腦的記憶體中有一塊空間稱為Heap來存放物件的本體2.當我們執行以下的程式碼後,電腦就會在Heap建立物件newStudent(...);3.當我們向下面宣告物件的變數時,只是產生一個用來記住物件地址的Reference而已Students;4.C#的程式執行時,背後有一個垃圾車會默默地檢查Heap,並刪除不需要的物件5.當一個物件沒有任何reference指向(儲存物件的地址)他的時候,就會被判定為不需要的物件相關資訊連結小山的C#教學-第16課-Value與ReferenceTypehttp://slmtsite.blogspot.tw/2013/03/c-16-value-reference-type.html維基百科-垃圾回收垃圾回收(計算機科學)垃圾回收(英語:GarbageCollection,縮寫為GC),在計算機科學中是一種自動的記憶體管理機制。
當一個電腦上的動態記憶體不再需要時,就應該予以釋放,以讓出記憶體,這種記憶體資源管理,稱為…zh.wikipedia.org九、小山的C#教學-第24課-封裝性PublicvsPrivate小山重點提示1.Public會使Property與Method變成任何人皆可觀看、使用與修改2.Private會使Property與Method變成只有自己皆可觀看、使用與修改3.一旦Property或Method被設為Private,那就只有同一個Class大括號範圍內的東西才有權限使用4.C#不加修飾字的話,就會自動設為「internal」,「internal」簡單地來說,就是只有「在同一個檔案內的地方」才有辦法存取的到補充存取權限為了要保護class內的某些東西不被隨意更動,C#提供控制存取權限的關鍵字。
而這些關鍵字,就是本課所教的public,private。
除此之外,C#還提供如protected,internal….等等關鍵字。
protected將會等到繼承性的教學才會提到,而internal則可能會在更之後的時候才會提。
現階段,public與private的控制就很夠用了。
相關資訊連結微軟官方(MSDN)對於「存取修飾字」的介紹存取修飾詞-C#程式設計手冊類型或成員可由相同組件或參考該組件的另一個組件中的任何其他程式碼存取。
Thetypeormembercanbeaccessedbyanyothercodeinthesameassemblyor…msdn.microsoft.com十、小山的C#教學-第25課-Private的常見用途privated可以拿來做什麼?狀況1.有些class的property不想讓人看到狀況2.有些class的property只想讓人看到,但是不想讓別人可以修改,那就把此property設定成private,然後寫一個public的Method給別人讀就好了(如下圖)狀況3.讓有些class的property在設定上增加一些限制就像只開放外面的人用public方法修改HP,而不能直接去存取HP,另外寫成方法做引用,也可以避免在很多地方重複寫很多次與寫錯的錯誤~小山重點提示private在以下三種狀況能夠使用:1.有些Property想要隱藏起來,不想讓class外的東西能夠隨意存取像是:Password密碼因此可以將Password直接設為private如果有比對密碼的需求,只需要簡單寫一個public的method來做比較的工作即可2.有些Property只想設成唯讀,就是只能看,不能夠修改像是:Account帳號同樣先將Account設成private然後建立一個public的method叫做getAcoount來讓class外的東西取得Account的內容3.想要讓某些Property在設定上有所限制像是:HP血量,限制:HP不可以為負數首先先將HP設為private然後建立一個public的method像是本課所提的hurt來間接設定它如果想要觀看HP的數值,只要像(2)一樣建立getHP的method即可補充==&equals(stringtarget)在本課中,我們有比對兩個字串是否相等。
相信有學過Java的人,應該會發現一件怪事。
為什麼比對字串相等是使用「==」,而不是用「equal(stringtarget)」?事實上,使用equals也正確。
但是在C#中,只要兩字串內的文字相同,就會參照到同個物件。
因此如果使用「==」去比較記憶體位置,也會得到相同的值。
這在Java裡面則會隨著建立String的方式不同而有所變化。
因此要記住,在Java內,比較字串相等一定要用「equals」;但在C#內,使用「==」也可以用做比較字串相等。
注意:以上畫線內容有誤,以下將作修正(2013/10/24)感謝網友「小明」提問,我才注意到這個錯誤我原本是說「只要文字相同,就會參照到同一個記憶體位置」,這句話其實只對一半。
事實上,C#有維護一個稱為「StringPool」(字串池、字串倉庫)的記憶體空間。
C#會在你的程式編譯的時候,就先把確定知道內容的字串變數都先檢查過,然後把這些字串的值都存在的StringPool裡面,最後讓值應該相同的變數指向同一個物件。
舉個例子來說,下面這段程式碼:Stringa="123";Stringb="123";我們不需要執行就知道a跟b的字串都是"123",所以C#就會讓a跟b指向同一個String物件。
但是如果是下面這種狀況:Stringa="123";Stringb="1";Stringc="23";//中間可能有其他程式碼Stringd=b+c;那麼C#就無法馬上知道d會等於多少,因為第四行程式碼可能離前三行很遠,中間b,c遭到修改也沒人知道,所以就算最後a,d都是"123",兩個也都會個別指向不同的物件。
另外還有一種情況:Stringa="ccc";Stringb=newString('c',3);上面這段程式碼,b會得到"ccc",也就是跟a一樣的字串。
但是因為我們利用new這個指令,強迫C#一定要建立一個String物件,所以就算程式在編譯的時候就知道a,b相等,仍會讓他們指向不同物件。
最後,以上所有結果,你們使用「==」去比較,還是會全部得到ture!為什麼?因為C#特別處理了String比較的情況!一般來說,如果拿ReferenceType的東西用「==」比較,確實會比較它們的記憶體位置是否相等。
但是C#有特別規定,如果被比較的東西是String的話,那麼就要比較它們的存的「值」是否相等。
不過,我個人建議大家,還是用equals來比較字串會安全許多。
另外,如果你們想要比較兩個字串的記憶體位置是否相同,那請使用:String.ReferenceEquals(ObjectobjA,ObjectobjB);詳細使用方式可以參考下面的連結。
相關資訊連結網友larrynung對StringPool的介紹http://www.dotblogs.com.tw/larrynung/archive/2011/06/30/30763.aspx微軟官方(MSDN)對於「==」運算子的介紹(裡面特別提到String比較的方式不同)http://msdn.microsoft.com/zh-tw/library/53k8ybth%28v=vs.90%29.aspx微軟官方(MSDN)對於ReferenceEquals()使用方法的介紹Object.ReferenceEquals(Object,Object)方法(System)判斷指定的DetermineswhetherthespecifiedObject執行個體是否為相同的執行個體。
Objectinstancesarethesameinstance.public:static…msdn.microsoft.com十一、小山的C#教學-第26課-Get&Set存取器小山重點提示1.Get&Set存取器的語法如下:.........//宣告變數(通常是public){get{....}//希望變數讀取時執行的程式碼set{....}//希望數值存入時執行的程式碼}2.如果只使用get而去除set的話,該變數將會變為唯讀3.使用Get&Set存取器時,並不一定要有對應的private變數4.Get&Set存取器可以用來即時運算一些平常大家認為是變數的數值,像是Money相關資訊連結微軟官方(MSDN)對於get的介紹http://msdn.microsoft.com/zh-tw/library/ms228503.aspx微軟官方(MSDN)對於set的介紹set關鍵字-C#參考TheFormoreinformationandexamples,seeset關鍵字會在屬性或索引子中定義「存取子」方法,以將值指派給屬性或索引子項目。
setkeyworddefinesanProperties…msdn.microsoft.com十二、小山的C#教學-第27課-所以到底甚麼是封裝性?小山重點提示1.所謂的「封裝性」指的就是:「隱藏物件內部的實作細節,只留下讓外人操作的介面(方法)」2.封裝性的好處有二:(1)保護物件內部的變數(2)隱藏實作細節,讓別人使用只需知道使用方法即可3.有一種技術稱之為「緊密封裝」,意思就是「把物件內所有Property都設成private,並只提供publicmethod或Get&Set存取器來供外界操作變數」補充存取範圍修飾字其實之前所教的public與private就是所謂的「存取範圍修飾字」,也就是只要加上其中一個關鍵字,就可以控制後面東西的存取範圍。
而在C#裡面,這類的修飾字一共有五個:public,protected,internal,protectedinternal,private。
第一個跟第五個想必大家都很清楚了,那麼其他三個又是甚麼呢?protected與protectedinternal與下一段「繼承性」有關,這邊暫不作介紹。
因此我們今天只討論internal,它的定義是「存取只限於目前的組件(assembly)」,好像有點難懂?我們來解釋一下。
不知道大家還記不記得,程式碼轉換成可以執行的檔案需要經過一個「編譯(Compile)」的動作?而所謂的internal,其實指的就是「在同一次編譯的所有程式碼之中,任何地方都可以存取」的意思。
假設你現在有兩個Class,A跟B,然後A之中有個變數:internalintnumber;這個時候,如果你先把ClassA編譯,並塞入一個程式庫(DLL檔),然後讓B去使用這個程式庫。
要是ClassB這個時候想要使用ClassA的number的話,就會發生錯誤!因為A跟B不是一起編譯的,這樣就不符合internal的要求。
所以當你不會單獨把一些class先編譯成程式庫,或是程式規模很小的時候,internal其實就跟public沒甚麼兩樣。
最後要注意,有沒有想過如果你沒有加任何存取範圍修飾字的話,那麼那些變數預設會是public還是private呢?這邊要告訴你,如果是物件的Property的話,預設的存取範圍就是internal喔!相關資訊連結MSDN-存取範圍層級http://msdn.microsoft.com/zh-tw/library/ba0a1yw2%28v=vs.90%29.aspxMSDN-internalinternal(C#參考)更新:2007年11月internal關鍵字是型別和型別成員的存取修飾詞。
內部型別或內部成員只能在相同組件中的檔案內存取,如本範例所示:publicclassBaseClass{//Onlyaccessible…msdn.microsoft.com十三、小山的C#教學-第28課-繼承性小山重點提示1.所謂的繼承性,指的就是「物件可以透過繼承,獲得其他物件的屬性與行為」2.在C#之中,想要使用繼承只需要在定義class時,於class名稱後面加上「:」(冒號)與被繼承的class名稱即可例如我想要讓classA繼承classB,就要寫成classA:B{...}相關資訊連結微軟MSDN對於「繼承」的介紹繼承-C#程式設計指南繼承是物件導向程式設計的三個主要特性之一,另外兩個是封裝和多型。
Inheritance,togetherwithencapsulationandpolymorphism,isoneofthethreeprimary…msdn.microsoft.com十四、小山的C#教學-第29課-繼承性(續)小山重點提示1.在C#之中,被繼承的Class被稱為「BaseClass」(基底類別),繼承的Class被稱為「DerivedClass」(衍生類別)2.除了上一課提到,我們可以透過繼承把多個Class重複的程式碼寫在同一個Class以減少「Class之間」的重複程式碼之外,我們也可以利用繼承減少「Class內部」的重複程式碼3.如果我們想讓Monster可以攻擊不同的生物,像是村民或其他怪物,那可能需要為不同的生物撰寫不同版本的Attack:publicvoidAttack(Villagervillager){....}publicvoidAttack(Monstermonster){....}但是我們都知道Villager與Monster就繼承自Creature,所以我們可以這樣寫:publicvoidAttack(Creaturecreature){....}這樣只要是Creature或是它的衍生類別,都可以被傳入Attack處理這樣就可以大大減少Class內部的重複程式碼補充Overloaded(多載)之前已經提過了何謂Overloaded,可以從下面的連結觀看之前的介紹http://slmtsite.blogspot.tw/2013/04/c-17-constructor.html相關資訊連結微軟MSDN對於「繼承」的介紹繼承-C#程式設計指南繼承是物件導向程式設計的三個主要特性之一,另外兩個是封裝和多型。
Inheritance,togetherwithencapsulationandpolymorphism,isoneofthethreeprimary…msdn.microsoft.com十五、小山的C#教學-第31課-Override覆寫子class繼承父class,子就會獲得父的屬性(欄位)與方法(行為)[問題]所有生物預設有攻擊能力,所以主角人物、史萊姆、怪物繼承生物,也都有攻擊能力,但是村民繼承生物時,如何只讓村民喪失攻擊能力??[問題]寫新的method(例如publicstringattack2())也能夠做到剛剛的事情,那為什麼需要override??小山答:使用override有另一個很大的好處,就是除了子class可以呼叫到自己的method之外,有用override的子method,也可以讓父class呼叫到!!![小知識]override好處,可以用父class的變數,來存取子class的物件!!![提醒1.]父class(就是classCreature)的methtod前有加virtual,這樣父class的move()與attack()才能被override。
[提醒2.]override的method其名稱與參數型別都要跟被override的相同,因為在C#中,有兩個method,名稱相同,但是signatures引數不同,那就變成overloaded多載的情形,也就視為不同method,所以不能override它。
[提醒3.]overloaded多載的另一個常見問題是,引數與method名稱都相同,但是output型別不同算是重複嗎?答案是,算!請看下面這個例子Example:intrun(){...}voidrun(){...}如果我今天呼叫run()的話,你可以辨別我是要呼叫哪一個run()嗎?相信你應該了解了吧?這就是為什麼這樣也算是重複的method。
小山重點提示1.Override指的是「改寫、覆寫」,主要是用來讓繼承的class改寫掉從baseclass繼承到的行為。
2.想要使用Override,首先必須要先在繼承的class中定義一個名稱與參數皆相同的method,然後在原本的method前加上「virtual」關鍵字,而新的method前加上「override」關鍵字。
補充Override使用時機基本上在撰寫物件導向的程式時,為了要讓許多物件有相同的動作,通常會寫一個class包含該動作,並讓其他class繼承它。
就像是這次課程中介紹的move或attack。
可是偏偏會有一些狀況會需要讓某些物件的行為與預設的不同,而當你需要這種修改時,就會用到override。
另外,Override也常用於多型性中,主要是因為它可以讓許多具有相同method的物件具有不同行為,這部分會在之後的課程中提及。
相關資訊連結MSDN—官方對於Override的說明override修飾詞-C#參考需要Theoverride修飾詞才能夠擴充或修改繼承方法、屬性、索引子或事件的抽象或虛擬實作。
overridemodifierisrequiredtoextendormodifytheabstractor…msdn.microsoft.com十六、小山的C#教學-第32課-OverridevsMethodHiding[觀念複習]A類別有繼承自B類別的話,那麼宣告出來(new出來)的A類別(子類別)的物件,就可以用B類別(父類別)的變數去存取A類別(子類別)的物件。
[舉例]有Apple類別繼承自Fruit類別,則Fruit父類別變數f,可以用Fruitf=newApple();去存取Apple子類別的Apple()物件。
A:父類別B、C:子類別[Override]B子類別改寫原本的A父類別的method[MethodHiding]C子類別建立新的method,與舊A父類別存在的virtualmethod共存,變數是C子類別就會呼叫到新的method,變數是A父類別就會呼叫到舊的method。
十七、小山的C#教學-第33課-Protected權限嚴格程度比較:Private(全關)>Protected(保護,部分開放,有繼承才能用)>Public(全開)下面舉一個Protected變數的例子:顯示結果是500,這代表:外部的magicButton_Click()方法內,new建立了史萊姆的物件後,成功驗證在史萊姆的publicSlime()方法內,已將hp=100改成hp=500,然後透過了史萊姆繼承怪物的publicintgetHp()方法,可以在外部的magicButton_Click()方法內,呼叫到getHp()的方法,然後取得HP數值=500這就是Protected的作用!!!Protected使用時機:用來控管不想讓外人隨意使用,但是又想讓繼承的Class內能存取的資源。
Protected對變數可以用,Protected對方法也是可以用!!因為把怪物內的自我介紹introduceSelf()方法設為protected所以就只能在繼承怪物的史萊姆Class中去使用introduceSelf()方法,外面其他沒有繼承怪物的Class是沒辦法直接碰觸到的。
外面其他沒繼承怪物的Class只能透過存取史萊姆的publicstringsay(),才能取得introduceSelf()方法的內容小山重點提示1.protected與public和private相同,都是用來進行權限控管的關鍵字2.套用protected的資源不可以直接從外界存取(類似private),但是可以從繼承的class之中存取3.開放程度:pubilc>protected>private相關資訊連結MSDN—protectedprotected關鍵字-C#參考Theprotected關鍵字是成員存取修飾詞。
protectedkeywordisamemberaccessmodifier.受保護的成員可在其類別內由衍生類別執行個體存取。
Aprotectedmember…msdn.microsoft.com十八、小山的C#教學-第34課-Base關鍵字十九、小山的C#教學-第35課-AbstractClass&AbstractMethod抽象類別與抽象方法Abstract抽象KK[ˋæbstrækt]重音在第一音節AbstractClass的好處,是可以放入一個AbstractMethod,但是!!!一般Method的組成:1.宣告2.內容(實際執行方式)注意!!!Abstractmethod沒有2.內容!!!!!只有1.宣告但實際上,這種abstractmethod是沒辦法做事情的,但是為什麼要有不能做事情的method??當需要強迫繼承的子類別實做(override)父類別的某些功能,就能使用abstractmethod!!![重點!!]abstractmethod可以把實作的工作,轉交給繼承的類別來定義!!另外,因abstractmethod使繼承的子類別使用了override,也間接擁有了override好處,也就是可以用父class的變數,來存取子class的物件!!!可以看前面十五、十六複習:十五、小山的C#教學-第31課-Override覆寫十六、小山的C#教學-第32課-OverridevsMethodHiding另外找到Allen大對abstractmethod的論壇回覆文章的解釋:http://www.blueshop.com.tw/board/FUM20050124192253INM/BRD200903161438213TP.htmlabstractclassAinterfaceIxclassB:A,Ix{…}上述的code,我稱它為”classB繼承classA,並實作Ix介面”我再列幾個狀況您參考一下1.如果classB繼承classA,而你不想要求B一定要覆寫什麼A的method,那麼classA是否宣告成abstractclass都可以2.如果classB繼承classA,而你不想要別人可以newA出來,那麼classA就可以宣告成abstractclass,classA裡不必宣告abstractmethod3.如果classB繼承classA,而你想要B一定要寫某些A的method(有點像B實作Ix的味道),那麼classA就可以宣告成abstractclass,並宣告abstractmethod,逼classB一定要寫那些method另外也找到劉逸大大的文章作抽象類別的觀念補充:https://antrash.pixnet.net/blog/post/71078905抽象類別的適用時機。
下面分兩點說明,第一:我想抽象類別的存在就如同上述抽象名詞的概念,我們都希望說的越少但能表示的越多,而抽象化能幫助我們達到此一目標。
相對的,在程式的世界中若想讓程式寫的越少卻能涵蓋的越多,那就要善用抽象類別,搭配前面我曾說過的多型一起使用,將可以達到:用越少的程式達到越多的效果。
第二:抽象類別中的抽象方法具備了規範的效果,當有一類別繼承了抽象類別,那勢必需要將抽象方法的內容重新定義(我們將此稱為『overriding』),這樣我們可以確保繼承抽象類別的子類別全部都會有抽象類別中的抽象方法重新定義之method。
等等~我想讀者已經頭暈了,換個實例說明,Animal是個抽象類別,當要繼承這個抽象類別時,必須把move()overriding,亦即將move的內容定義出來,如果是人那就是走路、獅子就是四條腿移動、魚就是游動,當你沒有重新定義函式,compiler會自動偵測並且回報錯誤來提醒工程師,這樣一來我們可以放心的用Animal這個抽象類別來動態操作下面的子類別囉~~善用抽象吧,越抽象往往威力越大。
能否理解用抽象反轉來操控底層的實體,是衡量一程式設計師是否具備優良的工匠技藝的關鍵指標之一。
Morefrom陳國仁FollowLovepodcastsoraudiobooks?Learnonthegowithournewapp.TryKnowableAboutHelpTermsPrivacyGettheMediumappGetstarted陳國仁23FollowersFollowHelpStatusWritersBlogCareersPrivacyTermsAboutKnowable
延伸文章資訊
- 1C# 类(Class) - 菜鸟教程
C# 类(Class) 当你定义一个类时,你定义了一个数据类型的蓝图。 ... 类的定义是以关键字class 开始,后跟类的名称。 ... 下面的实例演示了静态变量的用法: ...
- 2C# 認識物件 - HackMD
this 最經典的用法便是用在建構式,this 關鍵字用來強調當前執行的主角,在建構式中以區分跟主角相同名稱的變數傳遞值。 public class Employee { private str...
- 3類別
類別是使用 class 關鍵字來宣告,後面接著唯一識別碼,如下列範例所示:. C# ... 語言規格是C# 語法及用法的限定來源。
- 4C# Class, Object (static, public, protected, private)介紹- 教學 ...
在這裡,會介紹C#的Class 及Object基本用法. Class基本架構. 物件導向開發時,會運用class來作為資料型別. 這時,class就好像一個大類別,在這裡面, ...
- 5.NET 程式設計入門(使用C#)
用法 public class car. { string id;. } ○ 類別存取修飾詞. ○ public – 不同組件也可以被引用. ○ internal – 用一個組件才可以被引用(預...