二 物件和型別(第三部分)

2022-07-26 07:09:13 字數 3870 閱讀 7492

屬性(property)的概念是:它是乙個方法或一對方法,在客戶端**看來,它(們)是乙個字段。例如windows窗體的height屬性。假定有下面的**:

mainfrom.height = 400;

執行這段**時,窗體的高度設定為400,因此視窗會在螢幕上重新設定大小。在語法上,上面的**類似與設定乙個字段,但實際上是呼叫了屬性訪問器,它包含的**重新設定了窗體的大小。

1.唯讀和只寫屬性

在屬性定義中省略set訪問器,就可以建立唯讀屬性。

同樣的,在屬性定義中省略get訪問器,就可以建立只寫屬性。到那時,這是不好的程式設計方式,因為這可能會使客戶端**的作者感到迷惑,一般情況下,如果要這麼作,最好使用乙個方法代替。

2.屬性的訪問修飾符

c#允許給屬性的get和set訪問器設定不同的訪問修飾符,所以屬性可以有公有的get訪問器和私有或受保護的set訪問器。這有助於控制屬性的設定方式或時間。get訪問器具有屬性的訪問級別。在get和set訪問器中,必須有乙個具備屬性的訪問級別。如果get訪問器的訪問級別是peotected,就會產生乙個編譯錯誤,因為這會使兩個訪問器的訪問級別都不是屬性。

3.自動實現的屬性

宣告基本建構函式的語法就是宣告乙個與包含的類同名的方法,但該方法沒有返回型別。

沒有必要被類提供建構函式。一般情況下,如果沒有提供任何建構函式,編譯器會在後台建立乙個預設的建構函式。這是乙個非常基本的建構函式,它只能把所有的成員字段初始化為標準的預設值(例如,引用型別為空引用,數值資料型別化為0,bool為false)。這通常就足夠了,否則就需要編寫自己的建構函式。

建構函式的過載遵循與其它方法相同的規則。換言之,可以為建構函式提供任意多的過載,只要它們的簽名有明顯的區別即可。

但如果提供了帶引數的建構函式,編譯器就不會自動提供預設的建構函式。只有在沒有定義任何建構函式時,編譯器才會自動提供預設的建構函式。只有在沒有定義任何建構函式時,編譯器才會自動提供預設的建構函式。

注意,把建構函式定義為private或protected,這樣不相關的類就不能訪問它們。

注意:如果將建構函式定義為private的,這就是該類不能使用new運算子在外部**中例項化(但可以在該類中編寫乙個公有的靜態屬性或方法,以例項化該類)。這在下面的兩種情況下是有用的:

*類僅用作某些靜態成員或屬性的容器,因此永遠不會例項化它。

*希望類僅通過呼叫某些靜態成員函式來例項化(這就是所謂物件例項化的類工廠方法)

1.靜態建構函式

c#的乙個新特性是也可以給類編寫無引數的靜態建構函式。這種建構函式只執行一次,而前面的夠造函式時例項建構函式,只要是常見類的物件,就會執行它。

編寫靜態建構函式的乙個原因是,類有一些靜態欄位或屬性,需要在第一次使用類之前,從外部源中初始化這些靜態欄位和屬性。

.net執行庫沒有確保什麼時候執行靜態建構函式,所以不應把要求在某個特定時刻(例如,引導程式集時)執行的**放在靜態建構函式中。也不能預計不同類的靜態建構函式按照什麼順序執行。但是,可以確保靜態建構函式之多執行一次,即在**引用類之前呼叫它。在c#中,通常在第一次呼叫類的任何成員之前執行靜態建構函式。

注意,靜態建構函式沒有訪問修飾符,其他c#**從來不呼叫它,但在載入類時,總是由.net執行庫呼叫它,所以像public或private這樣的訪問修飾符就沒有任何意義。處於同樣的原因,靜態建構函式不能帶任何引數,乙個類也只能有乙個靜態建構函式。很顯然,靜態建構函式只能訪問類的靜態成員,不能訪問類的例項成員。

無引數的例項建構函式與靜態建構函式可以在同乙個類中同時定義。儘管引數列表相同,但這並不矛盾,因為在載入類時執行靜態建構函式,而在建立例項時執行例項建構函式,所以何時執行哪個建構函式並不會有衝突。

如果多個類都有靜態函式,先執行哪個靜態建構函式就不確定。此時靜態建構函式中的**不應依賴於其他靜態建構函式的執**況。另一方面,如果任何靜態欄位有預設值,就在呼叫靜態建構函式之前指定它們。

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

using

system.threading.tasks;

namespace

static

myclass()

public

void

print()

}class

program

}}

2.從建構函式中呼叫其他建構函式

有時,在乙個類中有幾個建構函式,以容納某些可選引數,這些建構函式包含共有的**。

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

using

system.threading.tasks;

namespace

public car(string _carname, int

_carage)

public

void

print()

}class

program

}}

這兩個建構函式初始化了相同的字段,顯然,最好把所有的**放在乙個地方。c#有乙個特殊的語法,稱為建構函式初始化器,可以實現此目的:

這裡,this 關鍵字僅呼叫引數最匹配的那個建構函式。注意,建構函式初始化器在建構函式的函式體之前執行。

c#建構函式初始化器可以包含對同乙個類的另外乙個建構函式的呼叫(使用前面介紹的語法),也可以包含對直接基類的建構函式的呼叫(使用相同的語法,但應使用base關鍵字代替this)。初始化器中不能有多個呼叫。

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

using

system.threading.tasks;

namespace

public car(string _carname, int _carage) : this(_carname, _carage, "新車"

)

public car(string _carname) : this(_carname, 0, "新車"

)

public

void

print()

}class

program

}}

3.唯讀字段

常量的概念就是乙個包含不能修改的值的變數,常量是c#與大多數程式語言共有的,但是,常量不必滿足所有要求。有時可能需要一些變數,其值不應改變,但在執行之前其值是未知的。c#為這種情形提供了另一種型別的變數:唯讀字段。

readonly關鍵字比const靈活得多,允許把乙個字段設定為常量,但還需要執行一些計算,以確定它的初值。其規則是可以在建構函式中給唯讀字段賦值,但不能在其它地方賦值。唯讀欄位還可以是乙個例項字段,而不是靜態字段,類的每個例項可以有不同的值,與const欄位不同,如果把唯讀字段設定為靜態,就必須顯示宣告它。

如果有乙個用於編輯文件的mdi程式,因為要註冊,所以需要限制可以同時開啟的文件數。現在假定要銷售該軟體的不同版本,而且顧客可以公升級他們的版本,以便同時開啟更多的文件。顯然,不能在源**中對最大文件數進行硬程式設計,而是需要乙個字段表示這個最大文件數。這個字段必須是唯讀的------每次啟動程式時,從登錄檔鍵或其它檔案儲存中讀取。

還要注意,在建構函式中不必給唯讀字段賦值。如果沒有賦值,它的值就是其特定資料型別的預設值,或者在宣告時給它初始化的值。這適用於唯讀的靜態欄位和例項字段。

物件導向 第三部分

示例 from abc import abc,abstractmethod 抽象基類 class animal abc 定義抽象方法 規定介面 abstractmethod defrun self pass 抽象基類不能例項化 a animal class cat animal 必須實現基類中規定的...

劇本第三部分

第三部分劇本 場景一 女生宿舍,a趴在桌子上睡覺,電腦螢幕亮著,是vs 但是就寫了一行 小碼趴在a的胳膊上睡著。突然,a醒了,發現自己上課要遲到了,a 哎呀,完了完了,大中午的怎麼趴在這睡著了 邊說話邊收拾書包 轉頭看向小碼 a 把你放哪呢 說話的時候四周環視 算了,跟我去吧,我先把你放書包裡 說話...

第三部分 效能

索引管理 效能優化 效能監控 db.c1.find explain 查詢的詳細資訊列出來 db.c1.getindexkyes 所有索引的字段 db.c1.getindexes 所有索引的相關資訊 2 唯一索引 只需要在ensureindex命令中提定 uniqure true 即可建立唯一索引,如...