標籤:order super 並且 空格 括弧 定義 oid 特性 根據
上一章筆者講到關於ADO.NET相關的知識,知道了如何去訪問資料庫。本章將來講關於物件導向的思想。不管在JAVA還是在C#物件導向思想的重要性都是佔了一個很大的成份。往往他就像呼吸一樣子,更多的時候我們會忽略。物件導向編程有三大特性:封裝、多態、繼承。關於這三大特性的定義筆者不會過多的介紹。網路上類似這樣子的文章一搜一片。相信裡面肯定有你需要的。而本系列主要目標是想讓JAVA程式員進入C#的開發環境。所以更多會在倆者之間的差別進行講解。
在進入物件導向思想的講解之前,筆者認為應該先明白什麼是類,什麼是對象,及他們之間的關係。這樣子的話才能更加明白物件導向思想。相關類和對象的講解在網路上一搜也是一大片資料。筆者不想過多的解講。筆者只是把自己的理解寫出來,希望能給大家一些協助。通常筆者喜歡把類理解為建房子時候用到的房子結構圖紙。而對象便是根據房子結構圖紙而建造成功的房子。這裡的圖紙便是.cs檔案,圖紙上面的結構圖就是類了。而建造成功的房子便是對象,也就是記憶體中的執行個體。這是筆者的理解。有了這一個之後,我們就來看一下三大特性。
對於封裝的裡面,筆者是這樣子看的。如果有過面向過程開發的讀者們就會明白。所謂的封裝就是把相關的資料放在同一個地區的,然後給這個地區命個名字。這樣子將來開發的時候就可以知道來源。代碼中的那個“.”就是最好的證明了。筆者不想講過多沒有用的話。我們就以代碼的形式來學習。如下
C#:
1 public class Person 2 { 3 public string Name { set; get; } 4 5 public string Sex { set; get; } 6 7 public void Move() 8 { 9 10 }11 }
筆者定義一個叫Person的類。顯然最大的區別在代碼的中的“{ set; get; }”這一個部分。相信JAVA中我們常常會看到一些習慣的寫法。算了。為了方便閱讀筆者還是寫代碼貼出來吧。
JAVA:
1 public class Person { 2 3 private String name; 4 private String sex; 5 6 public String getName() { 7 return name; 8 } 9 public void setName(String name) {10 this.name = name;11 }12 public String getSex() {13 return sex;14 }15 public void setSex(String sex) {16 this.sex = sex;17 }18 19 public void Move()20 {21 22 }23 24 }
我們可以看到JAVA這邊如果類外面的想要用內部成員的話,就必須通過對應的set或get方法來實現。而在C#中卻沒有這樣子寫法。他有自己一個概念叫屬性。上面的C#代碼就是屬性的寫法。只不過他還是縮寫的。為了學習我們還是在看一下正真的寫法吧。
C#:
1 public class Person 2 { 3 private string _name; 4 private string _sex; 5 public string Name 6 { 7 set { this._name = value; } 8 get { return this._name; } 9 }10 11 public string Sex12 {13 set { this._sex = value; }14 get { return this._sex; }15 }16 17 public void Move()18 {19 20 }21 }
上面的代碼就是C#屬性的完整寫法。可是C#開發人員往往不喜歡用而以。我們還都清楚知道JAVA在給類的內部成員變數賦值的時候,可能會做一些判斷或處理。 對應的C#這邊你們看到set後面的大括弧了沒有。就是在大括弧裡面寫。其中關鍵字value就是將來外面傳進來的值。代碼如下
C#:
1 public string Name 2 { 3 set 4 { 5 if (string.IsNullOrWhiteSpace(value))//判斷傳進來的值是不是空的。其中包括空格鍵 6 throw new ArgumentNullException("名字不能賦空值"); 7 this._name = value; 8 } 9 get { return this._name; } 10 }
C#屬性的使用:
Person person = new Person();person.Name = "Aomi";person.Move();
在我們建設類的時候,往往會定義一個叫常量的成員。JAVA用是關鍵字final來實現。而C#用的是關鍵字const。當然這裡還有一個關鍵字readonly。從某種意義來講他跟常量有一點類似。但又不能說是常量。只能說是一個唯讀變數成員。並且他們倆個在賦值的時候又有很大的差別。如下
關鍵字const:在定義的時候就要給也賦值。
關鍵字readonly:在定義的時候就要給也賦值。同時候在建構函式裡面。
C#:
private readonly string Nick ="aaa";public const string DefaultName = "Person";
除了賦值和定義不同之外,還有明白他們在使用的時候也不同。關鍵字const是用類來使用。如 Person.DefaultName。但是關鍵字readonly是對象內部自己的。這一點要注意。
當我們把資料封裝成為一個類的時候,我們要用這個類就必須跟類的建構函式打交道。這裡有著跟JAVA一個很大差別。如下代碼
C#:
public Person():this("Aomi") { } public Person(string name) { this.Name = name; }
從上面的代碼我們就能明白:JAVA的寫法是寫在建構函式裡面。而C#卻是在函數名後面。注意思加上“:”。
關於繼承的話,大多數跟JAVA沒有多的差別。主要是extends和implements都要用“:”來寫了。這一點到是比較JAVA簡單一點。而值得注意還有一點那便是跟建構函式有關係。我們都知道JAVA的super關鍵字吧。C#是用base關鍵字。同時用法不同。如下
public class Child : Person { public Child() : base("Aomi") { } }
筆者想了一會兒,覺得好像繼承這邊沒有別的不同了。
筆者個人覺得JAVA在多態這邊可能理解起來比較簡單。為什麼這樣子講呢?我們知道多態分為重寫和重載。其中最大的差別是在重寫身上。
1.重載。即是一名多用的意思。文法跟C#一樣子。必須要方法名相同,但是參數類型或是個數不同。
2.重寫。意思跟JAVA一樣子。只是寫法上卻有很大的不同。
C#的Person類:
1 public class Person 2 { 3 4 private string _name; 5 private string _sex; 6 public readonly string Nick ="aaa"; 7 public const string DefaultName = "Person"; 8 9 public Person():this("Aomi")10 {11 12 }13 public Person(string name)14 {15 this.Name = name;16 }17 public string Name 18 {19 set 20 {21 if (string.IsNullOrWhiteSpace(value))//判斷傳進來的值是不是空的。其中包括空格鍵22 throw new ArgumentNullException("名字不能賦空值");23 this._name = value;24 }25 get { return this._name; } 26 }27 28 public string Sex29 {30 set { this._sex = value; }31 get { return this._sex; }32 }33 34 public void Move()35 {36 Console.WriteLine("person move");37 }38 }
C#的Child類:
1 public class Child : Person 2 { 3 public Child() 4 : base("Aomi") 5 { 6 7 } 8 public void Move() 9 {10 Console.WriteLine("child move");11 }12 }
C#的Program類:
class Program { static void Main(string[] args) { Person person = new Child(); person.Name = "Aomi"; person.Move(); } }
執行結果:
我們看到上面代碼的執行結果是:person move。Child類重寫了Person類的Move方法,在用Person類封裝Child類執行個體。筆者用類似的功能在JAVA做了實驗發現執行結果是:child move。在C#這裡事實到關係到三個關鍵字:virtual、new、override。上面C#代碼中Child類的Move方法事實上是 public new void Move()。也就是說沒有重寫原來父類的方法。所以在執行用Person類封裝Child類執行個體的時候,會執行Person類的方法。所以C#這邊重寫的用法。應該是如下面這樣子。
C#的Person類:
public class Person{ public virtual void Move() { Console.WriteLine("person move"); }}
C#的Child類:
public class Child : Person { public override void Move() { Console.WriteLine("child move"); } }
看到了吧。父類如果將來有方法可能會被重寫的話,最好用關鍵字virtual來修飾這個方法。同樣子子類要重寫父類的話,就必須用關鍵override。至於關鍵new就是重新子類自己在寫一個方法,不影響父類。
本章主要講到物件導向在C#時候應該明白的一些地方。我們可以看到差別不大的繼承。封裝和多態還是有一定的差別。同是就是建構函式上的一些差別。
Java進擊C#——文法之物件導向