深入.NET平臺和C#編程

1.理解.NET Framework與C#

1-1:Microsoft.NET框架概述 a.Microsoft.NET介紹 .NET的戰略目標是在任何時候(when),任何地方(where)任何工具(what)都能通過.NET的服務獲得網絡上的任何信息, 享受網絡給人們的便捷與快樂. b..NET框架的特點 (1)它是.NET框架類庫中一個重要的組成部分 (2).NET框架爲我們提供了大量的類庫,它是一個巨大的寶藏,.NET應用程序可以使用這些類庫進行開發 (3)Visual Studio開發工具也可以使用VB.NET語言開發程序 (4).NET框架支持跨語言開發,只要是.NET框架支持的語言都可以實現相互調用和協作 c..NET框架概述 .NET框架非常強大,主要體現在以下幾種: (1)提供了一個面向對象的環境變量,完全支持面向對象編程.提高軟件的可複用性、可擴展性、可維護性、靈活性等。 (2)對Web應用的強大支持,如今是互聯網的時代,大量的網絡應用程序發揮着重要的作用。請查看:www.dell.com (3)對Web Server(Web)的支持,WebServer是.NET非常重要的內容。Hotmail和MSN登錄時都要使用Hotmail的賬戶... (4)Visual Studio是一個世界級的開發工具,它和.NET框架配合,能夠方便快捷地開發出多種.NET應用程序, 還可以進行測試、版本控制、Team開發和部署等。 1-2:.NET框架結構 a..框架結構 詳細請看P11頁 例如: .NET Framework .NET Framework類庫 Web窗體 Web Service WinForms ASP.NET ADO.NET和XML類 基本框架類 CLR CLS CTS 如上所示:框架結構中的組件

b.公共語言運行時 (1)CTS(通用類型系統) (2)CLS(公共語言規範) (3).NET編譯技術 例如: C#代碼【C#編譯器】 Microsoft中間語言(MSIL) 【CLR和JIT編譯器】--------平臺專用代碼 VB.NET代碼【VB.NET編譯器】 c.框架類庫 框架類庫中的核心部分包括以下幾點: (1)基礎數據的類庫,例如String類、集合、泛型等。 (2)I/O訪問,主要用於操作文件。 (3)安全控制,爲.NET安全機制提供一系列的功能。 (4)數據訪問,利用ADO.NET開發數據庫的應用程序。 (5)XML是用於描述數據的一種文件格式,它是.NET框架中很重要的一部分。 1-3:C#語言概述 a.C#語言的誕生 2000年,配合.NET平臺的發佈,微軟公司發佈了一門新語言:C#。它是專門爲.NET平臺設計的一種語言, 它的設計者Anders Hejlsberg是一位頗具傳奇色彩的人物。牛人:Anders Hejlsberg b.C#銳利體驗 (1)微軟公司已經向ECMA申請將C#作爲一種標準。 (2)完全的面向對象設計,在C#類型系統中,每種類型都可以看到一個對象。 (3)C#從2.0版本開始,對泛型提供了更完整的支持,泛型是微軟重點推出的內容,它可以使我們程序更加安全,代碼清晰,易控制。 (4)現如今,Web開發已經成爲軟件業的重點內容,並且C#語言與Web應用開發緊密地結合在一起。 (5)強大的類庫支持,C#有着數量龐大、功能齊全的類庫支持,可以簡單地完成複雜的加密操作、網絡應用操作等。 使用C#可以輕鬆地構建功能強大、開發快捷、運用方便的應用程序。 (6)可以利用C#開發多種應用程序,如Windows程序、ASP.NET、WebService等 例如: ASP.NET Windows Service C# Windows程序 Web服務 如上所示:C#開發多種應用程序

1-4:體檢框架類庫德強大功能 a.類庫的使用 例如: using System.Net; using System.Net.NetworkInformation;//引入命名空間 private void btnPing_Click(object sender,EventArgs e) { Ping pingSender=new Ping();//實例化Ping類 PingReply reply=pingSender.Send(txtIP.Text);//調用方法 if(reply.Status==IPStatus.Success) { string message=string.Format("地址:{0}連接測試成功!",txtIP.Text); MessageBox.Show(message); } else { string message=string.Format("地址:{0}連接測試失敗!",txtIP.Text); MessageBox.Show(message); } } b.框架類庫中的命名空間 框架類庫的內容被組織成一個樹狀命名空間(Namespace Tree).每一個命名空間可以包含許多類型及其其他命名空間。 System:"樹"的根 System.Data用於訪問ADO.NET System.Security提供系統的安全控制功能 System.Windows.Forms用於開發Windows應用程序,引入這個命名空間才能使用WinForms的控件和各中特性 System.Collections.Generic可以使用泛型 System.Net可以對網絡協議進行編程 c.定義自己的命名空間 using System; using System.Collections.Generic; using System.Text;

namespace MySchool { public class Student { } } d.命名空間的使用 (1)用自定義命名空間組織類 語法: namespace MySchool { class Student { //類的內容 public void Study(){} } } (2)引用命名空間 例如:using System.using MySchool (3)使用命名空間 使用命名空間中的類的方法是命名空間的名字加上"."再加上要使用的類名。例如:MySchool.Student; 使用時逐級地用"."連接,如:City.MySchool.Class.Student stu=new City.MySchool.Class.Student(); (4)命名空間的別名 例如: using System; using System.Collections.Generic; using user=City.MySchool.Class;//指定別名 namespace MyShool { class Student { user.Student stu=new user.Student();//使用別名調用 } }

2.用對象思考:屬性和方法

2-1:類和對象 a.一切皆對象 萬物皆對象 b.類和類的成員 (1)類的屬性 (2)類的方法 c.類和對象的關係 類和對象有着本質上的區別,定義了一組概念的模型,而對象是真實存在的實體,它們之間的關係如下: (1)由對象歸納爲類,是歸納對象共性的過程 (2)在類的基礎上,將狀態和行爲實體化爲對象的過程稱爲實例化 d.類和對象的使用 (1)將類實例化爲對象 (2)訪問對象的屬性或者方法 例如: Car ferrari=New Car();//實例化對象 Ferrari.Run();//調用方法或屬性 2-2:編寫一個自己的類 a.定義類和類的成員 語法: 訪問修飾符 class <類名> { //類的主體 } 例如: public class Student { int age=26; //姓名 private string name; public string Name { get{return name;} set{name=value;} } //問候 public void SayHi() { string message; message=string.Format("大家好,我是{0}同學。",name); MessageBox.Show(message); } } 注意: (1)字段用來表示類和對象相關聯的數據 (2)屬性用來表示類的狀態 (3)方法用來標識類的行爲 b.在類中添加屬性 例如: class Student { private string name;//姓名 public int age;//年齡 public string idNumber;//身份證號 } (1)訪問修飾符(2)數據安全(3)如何使用C#屬性(4)使用屬性的注意事項(5)屬性的類型(6)在編碼中如何快速地創建屬性(7)封裝 例如: (1)避免使用非法數據賦值 (2)保證數據的完整性 (3)避免類內部發生修改時,導致整個程序的修改 c.在類中使用方法 語法: 訪問修飾符 返回類型 方法名(參數) { //方法體 } 例如: private static void AddSocre(ref int refScore,out int scoreResult) { if(refScore>50 && refScore<60) { Console.WriteLine("你的成績在50-60之間,可以加分。"); refScore=60; } scoreResult=refScore; } (1)方法的返回值(2)方法的參數(3)使用方法(4)方法的重載(5)靜態方法和實例方法 靜態方法 實例方法 static關鍵字 不需要static關鍵字 類名調用 實例對象調用 可以訪問靜態成員 可以直接訪問靜態成員 不可以直接訪問實例成員 可以直接訪問實例成員 不能直接調用實例方法 可以直接調用實例方法和靜態方法 調用前初始化 實例化對象時初始化 d.使用構造函數創建對象 (1)構造函數的使用 (2)this關鍵字 使用構造方法請注意以下幾個問題: 一個類的構造函數名通常與類名相同 構造函數沒有返回值 一般情況下,構造函數總是public類型的 在構造函數中不要對類的示例做初始化以外的事情,不要嘗試顯示的調用構造函數,也就是直接去調用。 2-3:綜合實戰 (1)設計新聞閱讀器的類 (2)命名規範

3.用對象思考:值類型和引用類型

3-1:在類中使用幾種新的數據類型 a.在程序中使用常量 例如: public class Compute { double pi=3.14; //計算圓的周長 public double Perimeter(double radius) { return 2*pi*radius; } //計算圓的面積 public double Area(double radius) { return pi*radius*radius; } } 語法: 訪問修飾符 const 數據類型 常量名=值 例如 const int MAX_AGE=100; 但是,我們什麼時候使用常量呢? (1)用於在程序中一旦設定就不允許被修改的值 (2)用於在程序中被經常引用的值 b.使用枚舉避免不合理的賦值 (1)使用枚舉的妙處 例如: //... const string GENDER_M="男"; const string GENDER_F="女"; private string gender; public string Gender { get{return gender;} set{gender=value;} } //... 例如: public enum Genders//定義一個枚舉 { Male,Female } private Genders gender; public Genders Gender { get{return gender;} set{gender=value;} } //... //使用枚舉賦值 student.Gender=Genders.Male; //也可以這樣寫? student.Gender="ACCP";//這樣賦值是不能通過編譯的 (2)給枚舉成員賦值 例如: public enum Genders { Male=0,Female=1 } static void Main(string[] args) { stu.Gender=Genders.Male;

int genderNum=(int)stu.Gender; swtch(genderNum) { case 0: Console.WriteLine("您輸入的性別是-男"); break; case 1: Console.WriteLine("您輸入的性別是-女"); break; } } 注意: 程序中還可以獲取它的字符串表示 如:Console.WriteLine("您輸入的性別是{0}",stu.Gender.ToString()); 我們還可以從一個字符串中獲取枚舉的值 如:stu.Gender=(Genders)(Enum.Parse(typeof(Genders),"Female")) Console.WriteLine("您輸入的性別是{0}",stu.Genders.ToString()); 要從字符串轉換,需要使用Enum.Parse(),這個方法第一個參數是關鍵字typeof後跟放在括號中的枚舉類型, 第二個參數是要轉換的字符串。在方法最外面要使用枚舉類型進行強制轉換。 經驗: 枚舉可以使代碼易於維護,有助於確保給變量指定合法的、期望的值。 枚舉更易於輸入,如果我們使用枚舉賦值,則只要輸入枚舉名,然後打一個"."就能將所有的值顯示出來,減少了按鍵次數, 能夠然我們回憶起可選的值。 枚舉使代碼更清晰,允許描述性的名稱表示數據,使用時直觀方便 (3)我們曾經使用過的枚舉 例如: DialogResult choice; choice=MessageBox.Show("確定退出嗎?","退出系統",MessageBoxButtons.OKCancle,MessageBoxIcon.Information); if(choice==DialogResult.OK) { Application.Exit(); } OK:代表確定 Cancle:代表取消 c.它不是一個"類"---結構 (1)結構的定義 語法: 訪問修飾符 struct 結構名 { //定義結構成員 } 例如: struct StructStudent { public string Name; public Genders Gender; public int Age; public string Hobby; public int Popularity; public void SayHi() { ; }

} 注意:定義結構時的數據字段是不能賦初值的。 (2)結構的使用 例如: //... StructStudent myStu;//無需new myStu.Age=20; myStu.Gender=Genders.Female; myStu.Hobby="唱歌歌"; myStu.Name="張靚靚"; myStu.Popularity=100; //...

例如: stuct StructStudent { //... public StructStudent(string name,Genders gender,int age,string hobby,int popularity) { this.Name=name; this.Gender=gender; //... } } (3)結構和類的區別 類 結構 引用類型 值類型 可以被繼承 不能被繼承 可以有默認構造函數 不可以有默認構造函數 可以添加無參的構造函數 可以添加構造函數,但它們必需帶參數 創建對象必需使用new 創建對象可以不用new 類中可以給字段賦值 結構中給字段賦值是錯誤的

都可以包含字段、方法 都可以實現接口

3-2:理解C#中的值類型與引用類型 a.值類型 b.引用類型 c.裝箱和拆箱 例如: static void Main(string[] args) { ` `int i=123; object o=i;//裝箱 i=456;//改變i的內容 Console.WriteLine("值類型胡值爲:{0}",i); Console.WriteLine("引用類型胡值爲:{0}",o); }

例如: static void Main(string[] args) { int i=123; object o=i;//隱式裝箱 try { int j=(int)o;//拆箱 System.Console.WriteLine("取消裝箱成功."); } catch(System.InvalidCastException e) { System.Console.WriteLine("{0}錯誤:不正確胡取消裝箱.",e.Message); } } d.不同類型的參數傳遞 (1)值方式參數傳遞 (2)引用方式參數傳遞 例如: private void Vote(StructStudent stu) { stu.Popularity++; } //... StructStudent scofield=new StructStudent("",Genders.Male,28,"越獄獄"); scofield.SayHi(); Vote(scofield);//將值類型胡學員傳遞給這個方法 scofield.SayHi(); //...

例如: private void Vote(Student stu) { stu.Popularity++; } //... Student scofield=new Student("Scofield",Genders.Male,28,"越獄獄"); scofield.SayHi(); Vote(scofield);//人氣累加 scofield.SayHi(); 注意:雖然我們沒有使用ref方式傳遞,但是參數椒引用類型,當引用變量發生變化時,參數發生了變化。 所以,當類作爲參數的時候,可能修改類成員賦值。

(1)引用方式傳遞引用類型 例如: private void Vote(ref Student stu) { stu.Popularity++; } (2)引用方式傳遞值類型 例如: private void Vote(ref StructStudent stu) { stu.Popularity++; } e.細分值類型和引用類型 值類型 基本數據類型 整型 int 長整型 long 浮點型 float 字符型 char 布爾型 bool 枚舉 enum 結構 struct 引用類型 類 基類 System.Object、字符串 string、自定義類 class 接口 interface 數組 int[]、string[] 例如: private void TestArrayParameter() { int[] odd={1,3,5}; PrintArray(odd);//打印結果 ChangeToEven(odd); PrintArray(odd);//打印結果 } private void ChangeToEven(int[] arr) { for(int i=0;i<arr.Length;i++) { arr[i]=i*2; } } 輸出結果如下: arr[0]=1; arr[1]=3; arr[2]=5; arr[0]=0; arr[1]=2; arr[2]=4;

3-3:在類中使用索引器 a.索引器的使用 例如: public Student this[int index] { get{return students[index];} } public Student this[string name] { get { int i; bool found=false; for(i=0;i<students.Length;i++) { if(student[i].Name==name) { found=true; break; } if(found) { return student[i]; } else { return null; } } } } 訪問Student對象時,可以通過學員胡姓名訪問,也可以通過索引訪問。 MyClass myClass=new MyClass("T01"); myClass.Student[2].SayHi(); myClass.Students["黃超華"].SayHi(); b.索引器的特點及其應用 注意:定義一個索引器胡時候,要使用this關鍵字,而get和set訪問器也類似於屬性。索引器和數組屬性有些類似,但是 數組屬性只能通過下標(索引)訪問,而索引器可以通過重載它,從而自定義它的訪問方式。

3-4:使用類圖描述和類成員 描述類成員.如:屬性、方法... 詳細請看P77頁

4.用集合組織相關數據

4-1:集合概述 a.ArrayList (1)給ArrayList添加元素 語法: public int Add(Object value) (2)存儲ArrayList中胡單個元素 例如: Student stu1=(Student)students[0]; stu1.SayHi(); (3)刪除ArrayList中的元素 刪除ArrayList的元素有以下三種方式: 通過RemoveAt(int index)方法刪除指定index元素 通過Remove(object value)方法刪除一個指定對象名胡元素 通過Clear()方法一移除集合中所有元素 例如: //清除所有元素 students.Clear();

//打印集合數目 MessageBox.Show(string.Format("共包括{0}個學員。",students.Count.ToString())); (4)遍歷ArrayList中胡元素 例如: static void Main() { int[] array=new int[]{0,1,2,3,4}; for(int i=0;i<array.Length;i++) { Console.WriteLine(array[i]); } }

例如: //for循環遍歷 for(int i=0;i<students.Count;i++) { Student stuFor=(Student)students[i]; Console.WriteLine(stuFor.Name); } //foreach循環遍歷 foreach(Object stuo in students) { Student stuForeach=(Student)stuo; Console.WriteLine(stuForeach.Name); } (5)常見錯誤 將Student類改爲了Student結構 數組越界 刪除數據後,ArrayList的索引會自動分配和調整 b.HashTable (1)給哈希表添加元素 語法: public void Add(Object key,Object value) (2)獲取哈希表的元素] 例如: //使用Add()方法添加元素 students.Add(scofield.Name,scofield); students.Add(zhang.Name,zhang); students.Add(jay.Name,jay); //獲取指定的元素 Student stu2=(Student)students["周杰傑"]; stu2.SayHi(); (3)遍歷哈希表 例如: students.Add(scofield.Name,scofield); students.Add(zhang.Name,zhang); students.Add(jay.Name,jay); Student stu2=(Student)students["周杰傑"]; stu2.SayHi();

//元素遍歷 foreach(Object stuno in students.Values) { Student stu=(Student)stuo; Console.WriteLine(stu.Name); } (4)刪除哈希表胡元素 語法: public void Remove(Object key)

students.Add(scofield.Name,scofield); students.Add(zhang.Name,zhang); students.Add(jay.Name,jay); Student stu2=(Student)students["周杰傑"]; stu2.SayHi();

//元素遍歷 foreach(Object stuno in students.Values) { Student stu=(Student)stuo; Console.WriteLine(stu.Name); } //刪除元素 students.Remove("周杰傑"); 4-2:泛型與泛型集合 a.泛型 泛型有以下兩大優點: (1)泛型胡性能高 (2)泛型胡另一個優點是類型安全 b.泛型集合List<T> 語法: 定義一個List<T>泛型集合胡方法如下 List<Student> students=new List<Student>(); 例如: //訪問單個元素 //通過索引訪問,無須類型轉換 Student stu1=students[2]; stu1.SayHi(); //打印集合數目 MessageBox.Show(string.Format("共包括{0}個成員。",students.Count.ToString())); //通過索引刪除 students.RemoveAt(0); //打印集合數目 MessageBox.Show(string.Format("共包括{0}個成員。",students.Count.ToString())); foreach(Student stu in students) { //遍歷時無需類型轉換 Console.WriteLine(stu.Name); } List<T>與ArrayList的區別: List<T> ArrayList 對所保存胡元素做類型約束 啄增加任何類型 添加/讀取無須拆箱、裝箱 添加/讀取需要拆箱、裝箱

通過索引訪問集合中的元素 添加元素方法相同 刪除元素方法相同 c.泛型集合Dictionary<K,V> 語法: 定義一個Dictionary<K,V>泛型集合胡方法如下所示: Dictionary<String,Student> students=new Dictinary<String,Student>(); Dictionary<K,V>和哈希表胡對比: Dictionary<K,V> HashTable 對所保存元素做類型約束 可以增加任何類型 添加/讀取無需拆箱、裝箱 添加/讀取需要拆箱、裝箱 通過Key獲取Value 添加原始方法相同 刪除元素方法相同 遍歷方法相同 d.泛型總結 泛型的重要性體現在一下幾點: (1)解決國很多頻繁的操作問題 (2)提拱了更好的類型安全性 (3)CLR可以支持泛型,這樣使得.NET平臺都能夠使用泛型 4-3:綜合實戰 RSS閱讀器 5.文件讀寫與XML

5-1:文件 a.文件的應用 例如: .docx .RTF .TXT .XLS .HTML .PDF .TIFF .PSD .JPG .GIF .RAR .MP3 等等... b.如何讀寫文件 (1)創建一個文件流 (2)創建閱讀器或寫入器 (3)執行讀寫操作 (4)關閉閱讀器或者寫入器 (5)關閉文件流 注意:導入命名空間 using System.IO; 例如: private void btnWrite_Click(object sender,EventArgs e) { string path=txtFilePath.Text; string content=txtContent.Text; if(String.IsNullOrEmpty(path)==true) { MessageBox.Show("文件路徑不能爲空"); return; } try { //創建文件流 FileStream myFs=new FileStream(path,FileMode.Create); //創建寫入器 StreamWriter mySw=new StreamWriter(myFs); //將錄入胡內容寫入文件 mySw.Write(content); //關閉寫入器 mySw.Close(); //關閉文件流 myFs.Close();

MessageBox.Show("寫入成功"); } catch(Exception ex) { MessageBox.Show(ex.Message.ToString()); } } c.文件流 Creat 用於指定的名稱新建文件。如果文件存在,則會改寫舊文件。 CreateNew 新建一個文件。 OpenOrCreat:OpenOrCreate與Open成員類似,只是如果文件不存在,則用指定胡名稱新建一個文件夾並打開它。 (1)新建文件流 (2)關閉文件流 d.文件讀寫器 (1)StreamWriter寫入器 StreamWriter mySw=new StreamWriter(myfs); StreamWriter.Write();用於寫入流,這個流就是我們創建好的流。 StreamWriter.WriteLine();用於寫入一行數據,寫入某些數據後跟換行符。 StreamWriter.Close();用於關閉寫入器。 (2)StreamReader讀取器 StreamReader.ReadLine();讀取文件流中的一行數據,並返回字符串。 StreamReader.ReadToEnd();從當前位置讀到末尾,返回字符串。 StreamReader.Close();用於關閉讀取器。 例如: private void btnRead_Click(object sender,EventArgs e) { string path=txtFilePath.Text; string content; if(String.IsNullOrEmpty(path)==true) { MessageBox.Show("文件路徑不能爲空"); return; } try { //創建文件流 FileStream myfs=new FileStream(path,FileMode.Open); //創建讀取器 StreamReader mySr=new StreamReader(myfs); //讀取文件所有內容 content=mySr.ReaderToEnd(); txtContent.Text=content; //關閉讀取器 mySr.Close(); //關閉文件流 myfs.Close(); } catch(Exception ex) { MessageBox.Show(ex.Message.ToString()); } }

例如: //直接寫入方式 StreamWriter mySw=new StreamWriter(path); mySw.Write(content); mySw.Close();

//直接讀取方式 StreamReader mySr=new StreamReader(path); content=mySr.ReadToEnd(); txtContent.Text=content; mySr.Close(); e.文件和目錄操作 File類胡方法 Exists(String path) Copy(string SourceFilePath,string DestinationFilePath) Move(string sourceFileName,string destFileName) Delete(string path) Directory類的方法 Exists(string path) Move(string sourceDirName,string destDirName) Delete(string,bool) 靜態類與非靜態類 靜態類 非靜態類 用static 不用static修飾 只包含靜態成員 可以包含靜態成員 不可以包含實例成員 · 可以包含實例成員 使用類名調用靜態成員 使用實例對象調用非靜態成員 不能被實例化 可以被實例化 不能包含實例構造函數 包含實例構造函數 5-2:新聞閱讀器工作原理概述 a.新聞閱讀器工作原理 RSS閱讀器 b.XML概述 (1)保存 (2)說明數據【用途、關係】 例如: <Student> <Name>張靚穎<Name/> <Age>20</Age> <Hobby>唱歌歌</Hobby> <!-- --> <Name>周杰傑<Name/> <Age>22</Age> <Hobby>耍雙節棍棍</Hobby> </Student> 操作XML的對象屬性和方法 XmlDocument屬性和方法 DocumentElement屬性(獲取根節點) ChildNode屬性(獲取所有字節點) Load()方法(讀取整個XML的結構) XmlNode的屬性和方法 InnerText屬性(當前節點的值) Name屬性(當前節點胡名字) ChildNodes屬性(當前節點的所有字節點) 5-3:操作XML實現抓取新聞功能 a.遍歷XML 詳細請看P131頁 b.TreeView樹形控件 例如: private void btnLoadProfile_Click(object sender,EventArgs e) { pm.Load();//讀取配置文件 //遍歷頻道集合 for(RssFeed feed in pm.Profile.Feeds) { TreeNode feedNode;//定義一個TreeView節點 //將一個頻道標題加入節點 feedNode=tvMain.Nodes.Add(feed.DisplayName); foreach(Article atcl in feed.Articles.Values) { //在當前頻道節點上添加文章標題節點 feedNodes.Nodes.Add(atcl.Title); } } }

6.用對象思考:繼承

6-1:繼承概述 a.移除類中的冗餘代碼 例如: 在定義Student和Teacher類的類名後面都多出國":Person":class Student:Person,Class Teacher:Person. 我們稱這種方式叫做類的繼承。 b.什麼是繼承 一個類只能繼承另一個類 基類、父類 子類、地、派生類 滿足 is-a關係 c.繼承的實際應用 d.protected訪問修飾符與base關鍵字 例如: //在Person類中修改變量的訪問修飾符 protected string name; protected int age; protected Genders gender; //Student的構造函數 public Student(string name,Genders gender,int age,string hobby,int popularity) { this.name=name; this.age=age; this.gender=gender; //學生類擴展的屬性 this.hobby=hobby; this.popularity=popularity; }

6-2:繼承的使用 a.繼承的特型 (1)繼承的單根性 (2)繼承的傳遞性 (3)密封性 b.編寫子類構造函數的注意事項 (1)隱式調用父類的構造函數 (2)顯式調用父類的構造函數 c.繼承的價值 (1)繼承模擬了顯示世界的關係,OOP中強調一切皆對象,符合我們的面向對象思維。 (2)繼承實現了代碼的重用性,代碼更加清晰。 (3)繼承使得代碼結構清晰。 6-3:綜合實戰 a.擴展新聞快客 RSS閱讀器 (1)支持RSS/Atom兩種格式 (2)繼承機制給程序帶來的變化 b.窗體繼承 (1)首先創建基本窗體 (2)實現繼承窗體 (3)在父類窗體中實現公共的方法,例如退出等。 例如: partial class ChannelInfoAddForm:MyNewsReader.UI.ChannelInfoFormBase { //省略了窗體中的內容 } 7.用對象思考:多態

7-1:面向對象的多態性 a.巧妙解決繼承帶來的問題 不同的對象對於同一個方法調用,卻有着不同的執行結果,我們稱這種特性爲多態。 b.什麼是多態 多態是指兩個或多個屬於不同類的對象,對於同一個消息(方法調用)作出不同響應的方式。

7-2:使用抽象類和抽象方法實現多態 a.抽象類和抽象方法 語法: 訪問修飾符 abstruct 返回類型 方法(); 語法: 訪問修飾符 abstruct class 類名; (1)抽象方法是一個沒有實現的方法,通過在定義方法時增加關鍵字abstruct可以聲明抽象方法。 (2)含有抽象方法的類必然是抽象類。同樣,我們用abstruct關鍵字來定義一個抽象類。 b.常見錯誤 (1)對於一個抽象類有一個限制:它不能被實例化。 (2)抽象類不能是密封或靜態的。 c.抽象類和抽象方法的使用 (1)重寫抽象方法 (2)去掉獲取新聞列表功能中的多餘判斷 (3)抽象類和抽象方法的應用場合 語法: 訪問修飾符 override 返回類型 方法() 什麼時候使用抽象類和抽象方法呢? 例如: 貓和狗繼承自動物類,貓能喵喵地叫,狗能汪汪地叫,如果動物類是一個抽象類,它裏面有一個抽象方法"叫",理解爲:是動物都會叫。

d.里氏替換原則 (1)is操作符的使用 語法: if(obj is string) { } 例如: //判斷頻道是否是RSS類型 if(pm.Profile.Feeds[node.Index] is RssFeed) { rssFeed=(RssFeed)pm.Profile.Feeds[node.Index]; if(rssFeed.FetchArticles()) { UpdateArticlesView(node.Index); } } (2)as操作符的使用 獲取元素進行類型轉換。 7-3:使用虛方法實現多態 a.爲什麼要使用虛方法 例如:大家好,我是某某先生(女士),今年多少歲!!這個公告的SayHi()方法應該放在哪裏呢? b.虛方法的實際應用 (1)使用需方法實現多態 語法: 訪問修飾符 virtual 返回類型 方法() { //方法體 } (2)重新Equals()方法 語法: public virtual bool Equals(Object obj0) 需方法與抽象方法的區別: 需方法 抽象方法 用virtual修飾 用abstract修飾 要有方法體,哪怕是一個分號 不允許有方法體 可以被子類override 必須被子類override 除了密封類外都可以寫 只能在抽象類中 c.面向對象的三大特性 (1)封裝:保證對象自身數據的完整性、安全性。 (2)繼承:建立類之間的關係,實現代碼複用,方便系統胡擴展。 (3)相同的方法調用可以實現不同的實現方式。 7-4:簡單工廠設計模式概述 詳細請看P197頁 a.自動識別RSS與Atom b.簡單工廠設計模式

8.用對象思考:接口

8-1:接口 a.自定義對象的排序 注意:sort()方法,默認是升序的哈!! b.IComparable接口 語法: public interface IComparable { int CompareTo(Object obj); } 注意: 如果返回值小於0,則當前實例小於obj; 如果返回值大於0,則當前實例大於obj; 如果返回值等於0,則當前實例等於obj; 例如: class Student:Person,IComparable { //... //實現IComparable接口中的方法 public int CompareTo(object obj) { //判斷比較對象是否是Student對象 if(!(obj is Student)) { throw new Exception("只能與Student對象比較"); //將參數轉換爲Student對象 Student other=obj as Student; return this.Name.CompareTo(other.Name); } } } c.接口概述 接口就是一套規範,滿足這個規範的設備,我們可以將它們組裝在一起,從而實現該設備的功能。 (1)接口可以包含字段、屬性、方法、索引器等。但是不能實現,接口中的方法和屬性。 例如: 方法 public interface ISampleInterface { void ShowName(); } 屬性 public interface ISamepleInterface { string Name { get; set; } } (2)定義一個接口的名稱通常以"I"開頭 例如:IComparable、IList (3)我們習慣的說法是實現了一個接口、繼承了一個類 (4)實現一個接口的語法與繼承類似:class Student:IComparable (5)如果類已經繼承了一個父類,則以","分割父類和接口 無序之分 (6)class Student:Person,IComparable 如果有父類必須先繼承父類再實現接口,實現接口無順序之分哈! d.接口小結 (1)接口是對繼承的單根性的擴展,通過實現多個接口可以說是實現了一個類的多重繼承。 (2)接口是一中標準和規範 (3)接口屏蔽了實現的細節 比如:只定義,無需實現,也不能實現。 (4)接口得使用方便團隊開發協助

8-2:泛型接口 a.典型泛型接口IComparable<T>的應用 例如: class Student:Person,IComparable<Student> { //省略了構造函數和屬性 //IComparable<Student>成員參數必須是Student類型 public int CompareTo(Student other) { //比較返回結果,無需類型轉換 return this.Name.CompareTo(other.Name); } } b.IComparer<T>比較器 (1)Sort()方法的重載---Sort(IComparer<T>) 語法: public void Sort(IComparer<T> comparer) (2)IComparer<T>泛型接口 如果返回值大於0,則x>y. 如果返回值小於0,則x<y. 如果返回值等於0,則x=y. c.綜合實戰 RSS閱讀器 詳細情看P219頁 8-3:接口的典型應用 a.接口作爲參數的意義 接口作爲參數傳遞時,實際上要傳遞的就是實現這個接口的對象。在排序方法裏,調用集合的Sort()方法傳遞的就是實現了 IComparer<T>接口的類的一個對象:students.Sort(New NameComparer); b.接口作爲返回值的意義 接口是一組規範、一種標準,必須實現接口才能實現某個功能。典型的應用就是接口作爲參數時,我們要傳遞一個實現接口的 對象,另一個就是將接口作爲返回值,實際上要返回的也是實現了接口的對象。 c.接口和抽象類 抽象類與接口的區別 抽象類 接口 用abstract定義 用interface定義 只能繼承一個類 可以實現多個接口 非抽象派生類必須實現抽象類 實現接口的類必須實現所有成員 需要override實現抽象方法 直接實現

不能實例化 包含未實現的方法 派生類必須實現未實現的方法

9.序列化與反射

9-1:序列化與反序列化 a.擴展配置信息 注意: 在ProfileManager類中引入這樣一個命名空間 using System.Runtime.Serialization.Formatters.Binary; 語法: [Serializable] abstract class FeedBase { //... } 例如: public void Save { FileStream fileStream=null; //定義一個文件流 fileStream=new FileStream("profile.bin",FileMode.Create); //二進制方式 BinaryFormatter bf=new BinarryFormatter(); //序列化保存配置文件對象Profile bf.Serialize(fileStream,Profile); } public void Load() { FileStream fileStream=null; fileStream=new FileStream("profile.bin",FileMode.Open); BinaryFormatter bf=new BinaryFormatter(); Profile=(Profile)bf.Deserialize(fileStream); } b.特性 語法: [Serializable] abstract class FeedBase { //... } 例如: class Program { [Obsolete("不要使用舊的方法,請使用新的方法"),true] static void Old(){} static void New(){} public static void Main() { Old(); } } c.序列化 語法: pubilc void Serialize(Stream serializationStream,Object graph) serializationStream是指定序列化過程的文件流 graph是要保存的對象 例如: FileStream fileStream=nulll; //定義一個文件流 fileStream=new FileStream("profile.bin",FileMode.Create); //二進制方式 BinaryFormatter bf=new BinaryFormatter(); //序列化保存配置文件對象Profile bf.Serialize(fileStream,Profile); d.反序列化 語法: public Object Deserialize(Stream serializationStream) 注意:Deserialize()方法將存儲介值的數據文件流轉換爲Object,通常我們需要進一步將這個Object轉換爲相應的對象類型。 例如: public void Load() { FileStream fileStream=nulll; //定義一個文件流 fileStream=new FileStream("profile.bin",FileMode.Create); //二進制方式 BinaryFormatter bf=new BinaryFormatter(); Profile=(Profile)bf.Deserialize(fileStream); } e.序列化與反序列化的用途 (1)將數據保存在磁盤中,並在以後檢索此數據,將數據還原爲屬性和字段。 (2)將一個應用程序的東西發佈到另一個應用程序。 在三層中體現出來 (3)在遠程通信中應用非常廣泛,可以將一個應用程序中的對象序列化,然後通過網絡通信,遠程傳遞給其他地點的另一個應用程序 例如:WebService開發 9-2:程序集與反射 a.什麼是程序集 編譯好的.exe文件,稱爲程序集。程序集是.NET框架應用程序的生成塊,它包含編譯好的代碼邏輯單元。 b.程序集的結構 (1)程序集清單 (2)元數據 (3)其他內容 c.查看程序集 d.程序集中的訪問修飾符 類內部 同一程序集的工、派生類 同一程序集的其他子類 不同程序集的派生類 不同程序集的其他類 private 可以 不可以 不可以 不可以 不可以 protected 可以 可以 不可以 可以 不可以 internal 可以 可以 可以 不可以 不可以 public 可以 可以 可以 可以 可以 e.反射 導入 System.Refection.Assembly; 例如: class Program { static void Main() { string version=Assembly.LoadFile("D:\MyNewsReader.exe"); Console.WriteLine(version); } }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章