用《叩响C#之门》复习C#基础知识 第八章 面向对象编程:类和对象(二)
1、以對象為成員
類的成員不光可以是int、double等基本類型的變量,也可以是其他類的對象。其實也就是說,類的成員可以是所有的值類型和引用類型的成員變量。
2、靜態成員
1)靜態變量:描述類的整體特征的量可以用靜態變量實現,靜態變量在內存中只有一份,為類的所有對象共享。
靜態變量是描述整個類的,不管實例化多少個對象,在內存中只存在一份數據,所有的對象都可以使用它。
使用靜態成員不需要聲明對象,只需使用類名,比如Math類的成員基本上都是靜態成員,不必聲明Math類的對象即可使用各種數學常量和函數。
靜態變量只能在創建類時初始化一次,如果靜態變量比較復雜,可以定義一個靜態構造函數,用來專門初始化靜態變量。靜態構造函數也需用關鍵字static聲明。
類的所有對象共享靜態變量,也就是說對象可以通過類中的相關的函數來訪問靜態變量(也可以通過制作靜態變量對應的屬性來訪問和修改,這個屬性也可以定義為靜態的或非靜態的)。因此在類外,可以用靜態方法(或靜態屬性,屬性其實也是方法)直接訪問對應的類中靜態變量,也可用對象通過類中的非靜態函數(或非靜態屬性)訪問靜態變量。
?
沒有用static關鍵字修飾的變量稱為實例變量。實例變量通過對象名引用,靜態變量通過類名引用(需繼續深入!)。
?
2)靜態函數
在實際使用時,靜態方法只能訪問類中的靜態成員變量,而靜態方法內定義的變量屬于局部變量,局部變量不是類的成員,只是一段代碼塊中用到的變量而已,不存在靜態的說法!
?
3、常量成員
1)const常量成員
只能在聲明的時候初始化,不能在其他地方賦值,運行過程中它的值保持不變。
類的const常量成員是隱式靜態的,所有的對象都可以通過相關成員函數訪問它,類外要通過類名來引用const常量。
雖然const常量默認是靜態的,但不能用static關鍵字顯式聲明。
?
常量成員在訪問上與靜態成員變量方法類似,只是const常量成員只讀,不可寫而已。另外,const還可用于函數中局部常量聲明,而static只能針對類中的成員定義時用。
?
2)readonly常量
const常量是隱式靜態的,為同一個類的全部對象所共有,所有對象具有相同的值。
然而,在現實中,我們還需要一種常量,它在類的具體對象中是固定的常數,但在不同對象中可能是不同的值。這種常量用readonly常量實現。
聲明readonly常量語法:
訪問修飾符 readonly關鍵字 類型 常量名;
與const常量不同,readonly常量是非靜態常量,沒有要求在類中聲明時賦值,每個對象可以有不同的值,我們把readonly常量初始化代碼放在構造函數里,這樣每個對象就可以有不同的值。(在類中除了構造函數或變量初始值指定項,無法對只讀的字段賦值,變量初始值指定項指的是啥?在此存留疑問!)
readonly常量如果被定義為靜態常量,即在前面加static,稱為靜態只讀字段,此時只能在靜態構造函數或變量初始值指定項中對其進行賦值。
?
針對2、3兩點值得深入
?
4、重載
1)函數重載的調用原則是參數“最佳匹配(Best-fit)”,即系統調用參數類型最匹配的那個函數(參數數量、類型匹配的那個函數)。
2)構造函數的重載,這些構造函數均和類同名,但參數類型不同,系統自動調用參數完全匹配的那個構造函數。
3)運算符重載,由關鍵字operator聲明,必須定義為靜態!
訪問修飾符(一般為public) static 返回類型 operator關鍵字 運算符(如+) (左操作數類型 左操作數變量名,右操作數類型 右操作數變量名)
例子: public static A類名 operator + (A類名 a1,A類名 a2)
重載運算符的調用原則也是參數的“最佳匹配”,即系統是根據左右兩個操作數的類型選擇調用哪個版本的運算符。運算符見過去的隨筆
需要注意的是:&是按位與,|是按位或,^是按位異或,>>右移運算符,<<左移運算符,前面這5個都是二元位運算符;~是按位求補,是一元位運算符;比較運算符==和!=,>=和<,<=和>必須成對重載。
另外,不必重載“+=”、“&=”等這類復合運算符,因為A+=B會自動解釋為A=A+B,所以只要重載好+運算符就行了。
?
5、this關鍵字
在類外要通過對象名來訪問類的成員,但在類的定義代碼中,可以直接使用所有成員,其實每個對象都有一個指向自己的this引用符,一般情況下,在類的內部,你可以直接用類的成員,也可以通過this引用符使用變量。
?
6、索引
索引可以讓我們像數組那樣訪問類的數據成員。索引的函數體與屬性類似,也是get和set訪問器,get訪問器用于獲取成員變量的值,set訪問器用于為成員變量賦值。
定義方式如下:
訪問修飾符 數據類型 this 關鍵字 [下標類型 下標名稱]?? 這里的[]是[]運算符。
在數組中,下標只能為整數,在索引中,下標既可以為int型,也可以為double、string等類型!
C#還為我們提供了多維索引,只需提供多個下標即可。要用嵌套的switch語句實現。
?
7、值類型和引用類型
1)值類型變量
內存中有一塊區域成為棧(stack),用來存儲整型、實型、布爾型、字符型等基本類型數據。棧的壓入、彈出數據的操作總是發生在棧的頂部。
操作系統通過棧指針中存儲的地址讀寫棧中的數據,當棧為空時,棧指針指向棧的底部,隨著數據的不斷入棧,棧指針不斷向棧頂部移動,始終指向棧中下一塊自由空間。
當程序執行代碼塊,如執行到“float a=10.0F”時,將變量a的值壓入棧,同時指針向頂部移動4個字節,其他語句涉及到值類型變量賦值后,繼續將相關值壓入棧;當退出代碼塊時,程序依次將變量從棧頂部移出,直至棧指針指回棧底。
棧對數據的操作總發生在棧的頂部,最后入棧的變量最先彈出,最先入棧的數據最后彈出,因此先入棧的數據作用域總比后入棧的要長,后入棧數據的作用域嵌套在先入棧數據之中。棧的這種工作方式成為后入先出(Last In First Out,LIFO)。
整型、實型、布爾型、字符型等簡單數據和結構體存儲在棧中,稱為值類型變量(Value type)。
注意:C#不能使用未賦值的變量!只有賦過值的變量才能被使用。
?
2)引用型變量
棧有非常高的性能,但棧中的變量生存周期都是嵌套的,在類中,我們希望構造函數創建成員變量后,即使退出構造函數,這些變量仍然存在,其他函數仍然可以使用這些變量,為此C#把類的成員變量存儲在堆(Heap)上。
當創建了A類的對象時,系統做以下兩件事:
a、系統在堆中劃分一塊空間用于存儲對象的成員變量,并調用構造函數初始化對象的成員變量。
b、系統在棧中分配4字節(32位操作系統,即4字節的尋址)的空間,存儲對象在堆中的首地址。
?
棧中存儲的指向堆中對象的地址稱為引用符(Reference),系統通過引用符找到堆中的對象。
所有對象都存儲在堆中,數組也存儲在堆中,它們都稱為引用型變量(Reference type)。創建引用型變量比創建值類型變量復雜的多,雖然會造成一點性能上的損失,但可以對數據的生存周期進行非常強大的控制。
?
3)引用型變量和垃圾回收
在實際過程中,可能會有多個引用符指向同一個對象,當一個引用符退出作用域時,系統就會從棧中刪除該引用符。當指向對象的所有引用符都被刪除時,該對象就被加入垃圾回收的候選名單,垃圾回收器會在適當的時候清除該對象,只要有引用符指向對象,對象就不會被清除。
在.NET中使用的是托管堆,當垃圾回收器清除一個對象后,垃圾回收器會移動堆中其他對象,使它們連續地排列在堆的底部,并用一個堆指針指向空閑空間。當創建新的對象時,系統根據堆指針可以直接找到自由的內存空間。
垃圾回收器的整理工作是托管堆和傳統堆的區別所在,使用托管堆時,創建對象要快很多,雖然刪除對象時整理操作會浪費一定時間,但這些損失在其他地方得到很好的補償。
?
8、引用符和對象的區別
只有使用new運算符后,對象才真正被創建于堆中,才能使用對象的成員。當聲明一個對象時,那只是聲明了一個對象的名稱,僅在棧上創建了一個引用符而已,并沒有真的在堆中創建對象,對象的各成員是不存在的。
當對象沒有實例化時,引用符的值為null(空),當對象已經實例化,引用符的值就是該對象在堆中的地址。通過引用符中存儲的地址,系統可以輕易找到所要的對象。引用符是對象在內存中的地址,這一點在多態性中有非常明顯的體現。
?
9、聲明對象數組
類名[] 引用符=new 類名[對象元素的數量];
這只是聲明了一組引用符而已,原文中認為沒有真正創建對象,應該是不妥的(這句我寫錯了,作者已經親自上門指導,非常感謝!),應該是及創建了一組引用符,也創建了與各引用符關聯的對象。
using System; using System.Collections.Generic; namespace Test {public class Cat{private string name;string Name{get{return this.name;}set {name = value;}}public Cat(string nameVar){this.Name = nameVar;}public void DisplayName(){Console.WriteLine(this.Name);}}public class Program{static void Main(){Cat[] cat=new Cat[7];for(int i=0;i<7;i++){cat[i]=new Cat("Cat"+i);}foreach(Cat catVar in cat){catVar.DisplayName();}}} }輸出:
可見應該是及創建了一組引用符,也創建了與各引用符關聯的對象。(這句我寫錯了,作者已經親自上門指導,非常感謝!),
轉載于:https://www.cnblogs.com/365up/archive/2009/10/14/1583546.html
總結
以上是生活随笔為你收集整理的用《叩响C#之门》复习C#基础知识 第八章 面向对象编程:类和对象(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 导出EXCEL2003
- 下一篇: 【转载 译自MarketWatch 】