本文中,將要介紹與繼承相關的CLI主題,並以現實生活中銀行交易的三種形式:存款、取款、轉賬,來說明類的繼承體系,且以一種新的枚舉形式來實現。
枚舉器
請看例1中聲明的類型,它存在於其自身的源文件中,並編譯為一個只包含此類型的程序集:
例1:
public enum class TransactionType :
unsigned char {Deposit, Withdrawal, Transfer};
與想像的一樣,枚舉器中的Deposit、Withdrawal、Transfer分別代表0、1、2的常量值,但有三個方面卻讓這個enum類型與標准C++的enum類型(也就是"本地enum")大不相同。
·enum類只用於取代enum。這使TransactionType成為了一個CLI enum。(也允許enum結構,其與enum類等價。)
·此類型的可訪問性為public,以使其可從父類程序集外可見。(在C++/CLI中,一個本地enum類型也能有一個訪問限定符。)
·enum類有一個顯式的基本類型限定符:在本例中為unsigned char。(在C++/CLI中,一個本地enum也能有一個基本類型。)默認情況下,基本類型為int。基本類型也能為bool或除wchar_t之外的任意整形。(如果指定bool為基本類型,枚舉器必須顯式地進行初始化,因為沒有默認的初始值。)
支持這個新語法的原因是CLI enum遵從CLS標准,而本地enum卻不遵從。
CLI enum與本地enum間最大的區別在於構成方式上,枚舉名的作用范圍由它的父類enum類型來限定。另外,標准C++中定義的整數提升,並不適用於CLI enum。
與本地enum類似,一個CLI enum也能被定義在一個類中,在這種情況下,就不允許使用訪問限定符了,因為嵌套類型的可見性,已被其嵌入到的類型可見性所取代。
交易的抽象基類
交易類型的繼承體系在基類Transaction中,默認從System::Object繼承,見例2:
例2:
using namespace System;
using namespace System::Threading;
/*1*/
public ref class Transaction abstract
{
TransactionType typeOfTransaction;
/*2*/ DateTime dateTimeOfTransaction;
public:
/*3a*/ property TransactionType TypeOfTransaction
{
TransactionType get() { return typeOfTransaction; }
private:
void set(TransactionType value) { typeOfTransaction = value; }
}
/*3b*/ property DateTime DateTimeOfTransaction
{
DateTime get() { return dateTimeOfTransaction; }
private:
void set(DateTime value) { dateTimeOfTransaction = value; }
}
/*4*/ virtual void PostTransaction() abstract;
protected:
/*5*/ Transaction(TransactionType transType)
{
/*6*/ Thread::Sleep((gcnew Random)->Next(1000,2001));
/*7*/ TypeOfTransaction = transType;
/*8*/ DateTimeOfTransaction = DateTime::Now;
}
};
在標號1中,這個類被標為abstract(抽象類),這意味著它不能被直接實例化。(抽象不是一個關鍵字,僅僅在此上下文中作了保留。)這個abstract修飾詞可用於定義一個抽象類,而無須顯式地聲明一個或多個成員函數為純虛類型。
在類的私有數據成員部分,一個Transaction包含了一個交易類型及一個時間日期戳,兩者都由定義在標號3a及3b中的屬性來訪問。在標號2中使用的CLI庫值類型System::DateTime允許用一個即時變量顯示出當天的日期與時間。請注意,兩個屬性是怎樣擁有公有get方法與私有set方法的。(這是基於新的CLI標准,並且現在已與CLS兼容了。)