( 需注意程度:紅>粗體>下划線,藍色:我的疑問 )
- 老師的引言
- [師]對待一種新語言的關注點
- 數據類型定義(python不用定義)
- 語法
- JAVA兩大優勢
- 面相對象:比C++簡單
- 跨平台
- 開源:造就了很多免費的東西
- 每個button其實就是類的實例
- 找工作一定要有一技之長
- 面試內容:
- 大公司:基礎:C語言、數據結構
- 小公司:技術:C#、Java
- 數據傳遞(不確定正誤):
- 多數據傳遞:靜態類
- 單數句傳遞:構造函數
- 看懂書了再寫代碼
- [師]對待一種新語言的關注點
- 1 C#語言概述
- C#:
- 完全面向對象,設計一個程序就是設計一個或多個類
- 最長編寫的3種應用類型
- 控制台程序
- 窗體程序:窗體為.cs文件
- web應用程序
- 代碼:
- 托管代碼:
- 在CLR控制下運行
- 不能寫內存
- 是安全的
- 非托管代碼:
- 由操作系統直接運行
- 可以使用指針操作內存(所以指針是在操作內存)
- 不安全的
- 托管代碼:
- .NET Framework
- FCL(Framework Class Library):全面的類庫,包含大量處理常見的低級編程操作;由命名空間組成見p4-5
- CLR(公共語言運行庫):操作系統頂層,管理程序的執行,總的來說,包括:無用存儲單元的回收,代碼驗證和類型安全,代碼訪問安全
- CLS(Common Language Specification公共語言規范):定義了所有編程語言必須遵守的共同標准,語法
- CTS(Common Type System通用類型系統):定義了一套預定義數據類型。如:VB中的integer和C#中的int,在編譯后都映射為System.Int32,實現了不同語言數據類型的統一,從而實現跨語言功能
- 運行應用程序代碼的過程
- C#與. NET Framework的關系
- Visual C#集成開發環境
- 菜單
- 工具欄:菜單中常用的按鈕放到這里了,可在“視圖|工具欄”自定(我也要養成自定義工具欄的思維)
- 解決方案管理器:
- 解決方案名稱。解決方案包含項目。.slh可以打開整個項目
- 項目:包含於解決方案
- 引用:庫函數,指出程序引用的命名空間
- program.cs是代碼文件。所有C#代碼的源文件都是.cs(即C Sharp)為拓展名
- 編輯器設置:在 工具|選項(雖然是在菜單的某一選項,卻包含了整個軟件的設置)
- 項目的構成(目錄在 資源管理器 顯示)
- properties:
- 引用:指出程序引用的命名空間
- Program.cs
- namespace關鍵字的作用(using某些方面類似於c的#include):
- 組織代碼
- 分類管理
- 包含多個類
- namespace關鍵字的作用(using某些方面類似於c的#include):
- 其他
- Main()為程序入口
- 數據類型
- 值類型:直接存儲所包含的值(結構體是值類型),在棧空間分配
- 引用類型:存的是指針,指向它所要存儲的值(字符串是引用類型),其對象在堆空間分配
- C#:
- 2 C#程序設計基礎
- 變量的四個理解層面
- 變量的名稱:和該內存空間綁定在一起,對變量名稱的操作就是對內存空間的操作,也就是說程序員通過變量來使用計算機的內存空間。從系統的角度看,變量就是程序中的存儲單元,它既表示這塊內存空間的地址,也表示這塊內存空間中存儲的數據。
- 變量的值
- 變量的數據類型:決定了可容納什么樣的值,取值范圍,什么樣的操作可執行
- 變量的作用域和生命周期
- 數據類型:1值類型變量的內存開銷小、訪問速度快; 2引用類型變量內存開銷大、訪問速度稍慢; 3無論值類型變量還是引用類型變量,都是在棧空間中分配對應的存儲空間,所不同的是,引用類型變量所指的對象是在托管堆上分配內存空間
- 值類型
- 簡單類型:[師]類型轉換是一定要考慮溢出
- 結構類型:注意結構體是值類型
- 枚舉類型
- 引用類型
- 類
- string類:@ 字符串 為嚴格字符串,其中無轉義字符
- 接口
- 數組
- 委托
- 類
- 值類型
- 堆與棧:
- 棧:系統管理所有的棧空間
- 堆:程序可在堆中保存數據,但在c#中不能顯式地刪除他們,因為我們沒有指針,我們只管創建類的實例用就好了,CLR幫我們處理無用的對象
- 其他
- 拆箱和裝箱:即值類型和引用類型的轉換
- 結構類型:實際問題中,一組數據往往具有不同的數據類型,結構類型可以存儲多個不同類型的數據(我:分類是人類認識世界的方式,所以這個也是為了歸類,為了理清人類的思緒?),結構類型常規使用就是賦值和訪問
- 枚舉類型:用符號代替數據,提高程序的可讀性。如用X.red表示紅色。枚舉類型常規使用就是賦值和訪問
- 運算符:
- new:創建對象(我:這也當作運算符看?那什么不是運算符呢?)
- checked:啟用溢出檢查
- 常用類:1 C#是一種純面向對象語言,使用類和結構體來實現數據類型,而對象是給定數據類型的實例;2 C#中一切都是對象,例如,int數據類型就是一個類,它提供了相應的屬性和方法,int x=3這條代碼,int為類,x為對象。
- string類:
- 格式化字符串:Format()。有的函數庫中就有了,不要再造輪子了
- Math類:要寫計算器,根本不用自己實現那些復雜算法,直接用這些函數就可以了,一定要有這種思想,不要重復造輪子
- Convert類:值類型(?僅值類型嗎?書寫錯了?string也可以的啊)間的轉換
- string類:
- 問題:類語言和非類語言編譯器的實現有什么區別?
- 問題:靜態方法和動態方法有什么區別,為什么要做這種區分?
- 變量的四個理解層面
- 3 C#控制語句
- [師] if{ if..... }else{ if..... }如果有很多判斷,寫在黑體的if不易讀,寫在划線的if更易讀
- 循環控制語句:for通常用於已知循環次數(for只能用於已知循環次數,這句話是錯的)
- [師] 我(俞定國老師)當年是紙上寫一遍,腦子驗證,然后敲在電腦
- break,continue用於跳出循環(故寫在if中,跳出的是if外的循環)
- 閱讀代碼的方法:閱讀代碼只看關鍵的,細節都忽略
- while后的表達式為邏輯表達式或關系表達式
- 4 數組和集合
- [師] c的強勢在於
- 指針
- 位運算:直接到低層內存的運算
- [師]1先寫各種代碼,然后向上向下拓展。2代碼要分塊,也就是把步驟和功能分割開
- 數組
- 數組是引用類型,通過一個名稱來存取,所有值放在內存的一段連續空間,為了區分不同的值,添加了一些索引或下標。
- 集合和數組不同的地方在於:可動態增減
- 通常把二維數組叫做矩陣
- 數組的動態初始化(new)和靜態初始化,只不過是編譯時間不同,結果是一樣的
- foreach(var 迭代變量 in 數組或集合)
- 有些情況為了簡單,數組下標中的0總是不用
- Array類:所有數組的抽象基類。在C#中,數組實際上是對象,而不像C/C++中那樣的可尋址連續內存區域
- (我:對象不是 可尋址連續內存區域 ?)(我:什么是對象,什么是可尋址連續內存區域)。
- 靜態方法+動態方法
- ArrayList類 [師]:重點掌握,不像C需要自己控制
- Array類的優化版本,容量或元素個數不像Array是固定的
- 可存放多重數據類型,其用的數據類型是Object
- Array是多維的,ArrayList是一維的
- 均非靜態方法
- List<T>類:是ArrayList類的泛型等效類 [師]:重點掌握,不像C需要自己控制
- 數據類型是指定的
- 均為非靜態方法
- 這個有一個方法叫ForEach可以對每個元素執行指定操作
- 數組、List和ArrayList的區別
- 數組在內存中是連續存儲的,所以它的索引速度是非常的快,而且賦值與修改元素也很簡單,但是數組也存在一些不足的地方。比如在數組的兩個數據間插入數據也是很麻煩的,還有我們在聲明數組的時候,必須同時指明數組的長度,數組的長度過長,會造成內存浪費,數組和長度過短,會造成數據溢出的錯誤。這樣如果在聲明數組時我們並不清楚數組的長度,就變的很麻煩了。C#中最先提供了ArrayList對象來克服這些缺點
- ArrayList是數據存儲和檢索的專用類,大小是按照其中存儲的數據來動態擴充與收縮的。因為ArrayList會把所有插入其中的數據都當作為object類型來處理。這樣,在我們使用ArrayList中的數據來處理問題的時候,很可能會報類型不匹配的錯誤,也就是說ArrayList不是類型安全的。既使我們保證在插入數據的時候都很小心,都有插入了同一類型的數據,但在使用的時候,我們也需要將它們轉化為對應的原類型來處理。這就需要裝箱與拆箱的操作,會帶來很大的性能損耗。(該類的方法索引均從0開始)
- 所以在C#2.0后出現了泛型的概念。List<T>類 在聲明List集合時,我們同時需要為其聲明List集合內數據的對象類型。通過允許指定泛型類或方法操作的特定類型,泛型功能將類型安全的任務從您轉移給了編譯器。不需要編寫代碼來檢測數據類型是否正確,因為會在編譯時強制使用正確的數據類型。減少了類型強制轉換的需要和運行時錯誤的可能性。泛型提供了類型安全但沒有增加多個實現的開銷。(List list = new ArrayList();這句創建了一個ArrayList的對象后把上溯到了List。此時它是一個List對象了,有些ArrayList有但是List沒有的屬性和方法,它就不能再用了。 而ArrayList list=new ArrayList();創建一對象則保留了ArrayList的所有屬性。 )
- 考試前要看一遍正確的定義數組的幾種方式,否則會混淆!考后這句話就刪除掉吧
- [師] c的強勢在於
- 5 面向對象程序設計
- [師]:面向對象中,有20%的知識常用,就像搭積木,你只需要搞定用的東西
- 對象之間通過一定的“相互操作”傳遞信息([師金哲凡]:傳遞消息是一種設計概念,落實到語言上就是函數調用),在消息的作用下完成特定功能。
- 封裝:尚未理解
- C#實現運行時多態性的基礎是動態方法調度,它是一種在運行時而不是在編譯期調用重載方法的機制。(不能完全理解后面這句話的意義)
- 從計算機語言角度來說,類是一種數據類型,而對象是具有這種類型的變量
- 通常用數據成員模擬現實世界事物的特性,通常用函數成員模擬現實世界的功能和操作
- 無修飾符時,默認為私有的
- 類和結構類型很相似,但也有不同,主要差異如下
- 對象瀏覽器和類圖方便程序員進行面向對象的程序設計
- 對象引用變量在棧空間分配,實例在堆空間分配
- 沒有引用變量指向的堆空間會被CLR收回
- using 命名空間,注意using不是加的類,而是命名空間
- 當定義類對象時,構造函數會被自動執行,當類對象銷毀時,析構函數會自動執行
- 自己寫了含參數構造函數,記得自己寫一個默認函數
- 靜態成員屬於類所有,非靜態成員屬於類的對象所有。提出靜態成員概念的目的是為了解決數據共享的問題
- 靜態和非靜態的存儲方式
- 靜態構造函數的特點:不會繼承,在所有的構造函數中最先被執行
- 問題:屬性是強化的字段,弱化的方法,right?
- Main()是每個C#應用程序入口,在啟動時由公共語言運行庫調用
- 方法中的參數是保證不同方法間互動的重要“橋梁”,方便用戶對數據進行操作
- 方法的參數類型(注意參數是值還是引用就容易多了)
- 值類型
- 在棧中為形式參數分配空間
- 計算實參的值,並把該值復制給形式參數
- 注意體會這張圖和代碼
- 引用參數
- 不會在棧上分配空間
- 形參將作為實參的別名
- 注意體會這張圖和代碼
- 輸出參數
- 也不開辟新的內存區域
- 參數數組
- 可選參數
- 值類型
- this關鍵字:對當前實例的引用
- 對象的復制:非靜態方法Object.MemberwiseClone()來實現
- 淺復制:共享除String的所有引用成員實例
- 深復制:需自己創建新的引用類型,C#並沒有嵌入在語言中
- 嵌套類:未細看,用時看p119-p121
- 索引器:類似於屬性,不同在於訪問器采用參數。索引類型並不限制為整數。它的引入為了使程序更加直觀、易於理解。索引器的聲明、使用如下:
- 委托:即函數指針,不同於c/c++,可以與多個方法關聯在一起,可以把委托對象看成一系列方法,使用. +=委托對象 .增加方法,委托封裝的多個方法都會被一次性一起調用。聲明與使用:
- 事件:委托(函數指針)是事件的基礎。在事件通信中,事件源類不知道哪個對象或方法將接受到(處理)它引發的事件,所需要的是在源和接收方之間存在一個媒介(或類似指針的機制)。使用與分析見下圖:
- 犯錯截圖:
- 6 繼承和接口設計(習題尚未做)
- 繼承
- 為了對現實世界中的層次結構進行模型化,面向對象的程序設計技術引入了繼承的概念
- 派生類對象也是基類的對象,所以基類的引用變量可以引用基派生類對象(注意勿反,這兩句話句話和一般的世界規律有點不同)
- 除了構造函數和析構函數,派生類隱式地繼承了基類所有成員
- 基類的private不能被繼承(待查詢)
- (問題:那上一句話是不是說錯了?“除了構造函數和析構函數,派生類隱式地繼承了基類所有成員”)
- 構造函數:從最遠開始調用
- 析構函數:從最近開始調用
- (問題:一個類只能有1個析構函數,為什么?不是可以兩個嗎?自己的一個,CLR默認的都有一個?)
- 繼承使得程序允許創建分等級階層的類
- 【師】:默認構造方法建議都寫上,不要忽略
- 多態性
- 多態性是指發出同樣的消息(如方法調用)被不同類型的對象接收時可能導致不同行為
- 隱藏基類方法:用new關鍵字(注意:並非直接重寫,有意隱藏要用new)
- 重寫基類方法:適用情景:同一簽名的方法實現相同的目標,但在不同的地方有不同的實現細節,此時就需要用虛方法實現該方法的不同細節。 調用虛方法時,首先調用派生類中的該重寫成員,如果沒有派生類重寫該成員,則它可能是原始成員
- 在基類使用virtual關鍵字(不能與static、abstract、override一起用)
- 在子類使用override關鍵字
- 一個基類對象引用變量可以指向其子類的對象(記憶方法:父親可以指着兒子(罵))
- is運算符:檢查是否為該類型或可以轉換為制定類型
- as運算符:在兼容的引用類型之間執行轉換
- 易混的重寫和重載對比
- 重載:同一個類,同一個方法的多種形式,簽名不同
- 重寫:父子類, 同一個方法重寫, 簽名相同
- 抽象類
- 一個類不與具體的事物相聯系,而是表達一種抽象的概念,僅僅作為其派生類的一個基類
- 派生抽象類的非抽象子類必須實現所有抽象方法和抽象訪問器
- 尚未理解內容(下方):
- 其他注意事項:
- 接口
- 接口是類之間交互內容的一個抽象,把類之間需要交互的內容抽象出來定義成接口,可以更好地控制類之間的邏輯交互。接口最適合為不相關的類提供通用的功能。一個接口可以被多個類繼承,在這些類中實現該接口的成員,這樣接口就起到了提供統一界面的作用。
- 接口不包含方法的實現
- 接口不能定義字段、構造函數、常量和委托。
- 所有接口成員默認是公有的,在接口中聲明任何修飾符都是錯誤的。
- 接口和抽象類的異同
- 接口的實現:
- 隱式實現(即實現不包含接口完整名稱):接口成員必須是公共的、非靜態的
- 顯式實現(即實現包含接口完整名稱):不能使用任何修飾符。(如果沒有充分理由,應避免顯式定義接口成員)
- 接口映射:接口通過類實現,對於接口聲明中的每一個成員都應該對應類的一個成員,這種對應關系由接口映射來實現。
- 一個接口成員確定哪一個類的成員呢?假設類C實現了接口Ia的一個接口fun,此時fun的映射過程如下:
- ①如果類C中存在一個顯式成員實現,它與Ia的接口成員的fun相應,則由它來實現fun成員。
- ②如果在類C中找不到匹配的顯式接口成員實現,則看類C中是否存在一個與fun相匹配的非靜態的公有成員,若有,則認為是Ia的接口成員的fun的實現。
- ③如果以上都不滿足,則在類C的基類(父類)中尋找一個基類D,用D來代替C進行重復尋找,直到找到一個滿足條件的類成員實現。如果都沒找到,則報告一個錯誤。
- 一個接口成員確定哪一個類的成員呢?假設類C實現了接口Ia的一個接口fun,此時fun的映射過程如下:
- 看書p162-p164三個例子,接口實現的繼承很容易混。
- 上圖162頁第一個例子仍未搞懂
- 接口在集合排序中的應用
- Array.Sort():使用每個元素的ICompareable接口實現對整個ArrayList中元素的排序
- Array.Sort(IComparer):使用指定的比較器。(把接口對象作為參數傳遞給Array.Sort())
- 繼承
- 7
- 8
- 9 Windows應用程序設計
- 熟練掌握各個控件的屬性設置和方法調用是采用C#語言設計界面友好的應用程序的基礎(黑體中的兩點即為主要學習內容)
- 窗體是一個容器
- 通過設置控件的屬性可以改變其外觀和標題信息(屬性和外觀是一體兩面的東西)
- 每個窗體對應3個文件,即兩個。cs文件和一個。resx文件。前者為C#文件,后者為資源文件。
- 窗體各事件的引發順序
- 焦點與Tab鍵次序:視圖 | Tab鍵順序
- 常用的控件設計
- 所有控件基本屬性
- Name屬性:通過此名稱來引用這個控件
- Text屬性:獲取用戶輸入或顯示文本
- Size、Location
- Font
- BackColor、ForeColor
- Cursor:獲取或設置 鼠標的光標
- Visible、Enabled:Enabled決定了該控件是否被使用
- 控件的外觀和行為(如控件的大小、顏色、位置以及控件的使用方式等)是由它的屬性決定,不同的控件擁有不同的屬性,並且系統為它們提供的默認值不同。
- 控件RichTextBox
- 控件GroupBox分組框:用於分組(視覺上:歸類;功能上:單選)
- 控件CheckBox復選框:
- 屬性Checked:獲取或設置一個布爾值
- MessageBox(並不是該控件,不過是書中在此介紹):其返回值DialogResult,是通過事件來返回的。
- 控件RadioButton單選按鈕:搭配GroupBox一起使用
- 控件PictureBox
- 作用
- 做容器
- 放圖片
- 屬性Image:Image.FromFile函數加載圖像(路徑用絕對路徑不好)
- (問題1:如果書中沒有出現這段話,怎么知道有這個方法呢?!)
- (問題2:屬性.方法 屬性和方法什么關系啊?!)
- 作用
- 控件ComboBox組合框
- Items的屬性和方法
- Items的屬性和方法
- 控件ListBox列表框
- 屬性SelectionMode:值MultiExtended,為允許搭配shift或ctrl鍵的功能
- 事件KeyPress:在控件有焦點的情況下按下任何按鍵時發生
- 例子:
- 控件CheckListBox:繼承自ListBox,增添了復選框功能
- 控件Timer定時器(學會用庫很重要!我原來不知道竟然想自己寫一個定時器):
- 屬性Interval:兩個定時器事件之間的時間間隔
- 其他備注:
- 所有控件基本屬性
- 多個窗體之間的數據傳遞
- 通過靜態字段傳遞數據
- 通過構造函數傳遞數據(把數據放在參數中)
- 創建事件過程(多個事件可以連接到單個事件過程)
- 在Windows窗體創建
- 在執行時為Windows窗體創建
- 在Windows窗體創建
- 10 用戶界面設計
- 菜單:
- 分類
- 下拉式菜單:MenuStrip控件
- 彈出式菜單(右鍵彈出的菜單):需要將Form的ContextMenuStip屬性設置好,才能彈出
- 每個菜單項都是一個ToolStripMenuItem對象,可以把菜單它理解為容器。菜單項唯一的事件就是Click事件
- 熱鍵設置:菜單的文字,&后加的字母 將作為該菜單項的熱鍵
- 分類
- 通用對話框用:用ShowDialog方法顯示
- OpenFileDialog:打開文件:返回值為DialogResult
- SaveFileDialog:保存文件
- ColorDialog:選擇顏色
- FontDialog:選擇字符
- PrintDialog:打印文件
- PrintViewDialog:打印預覽
- 圖像列表框控件:ImageList
- 專門負責管理圖片
- 有幾套需要管理的,就創造幾個對象來管理
- 非可視化控件
- 樹形視圖控件:TreeView
- (問題:P271,方法和事件到底有什么區別,為什么分開說)
- TreeView中的結點的組織關系是父結點 管理 子結點(管理即:添加、刪除)
- Nodes是TreeView控件的一個屬性,它也是一個結點集合,每個結點就是一個Tree Node對象
- TreeNode對象的屬性和方法:P272
- 列表視圖控件:ListView
- 可包含多項,由Items集合表示,每一項就是一個ListViewItem對象,而每一個ListViewItem由其SubItems集合表示
- ListView的Columns集合屬性,由ColumnHeader對象組成
- 工具欄控件(本質:圖片按鈕):ToolStip控件
- 狀態欄控件(和Label差不多):StatusStip
- 菜單:
- 11
- 12 文件操作
- 輸入:文件中的數據讀取到內存中
- System.IO模型提供了一個面向對象的方法來訪問文件系統。以流(Stream)的方式對各種數據進行訪問,這種方式不僅靈活,而且可以保證編程接口的統一。
- (問題:體現在哪?以前沒有流操作是怎樣的?)
- 文件操作的基本方式:
- 用File類打開文件
- 建立對應的文件流,即FileStream對象
- 用StreamReader/StreamWriter類對文件(文本文件)流讀/寫 or 用BinaryReader/BinaryWriter類對文件(二進制文件)流讀/寫
- 文件夾和文件的操作
- 文件夾的操作:
- Directory類:均為靜態方法
- DirectoryInfo類:均為非靜態方法
- 文件的操作:
- File類:均為靜態方法
- FileInfo類:均為非靜態方法
- 文件夾的操作:
- 文件流的產生-FileStream類
- 文本文件的操作-StreamReader/StreamWriter類
- 二進制文件的操作-BinaryReader/BinaryWriter類
- 序列化和反序列化:將對象的公共字段、私有字段、類的名稱(沒有方法、事件)轉換成字節流,然后寫入數據流,反序列話反之。使用序列化可以將隨想從一個應用程序傳遞給另一個應用程序。實現方法如下:
