存款、取款、转账类
例3定义了存款类,为什么这个类为sealed呢?如果还没有认真考虑过它是否足够"健壮"以可作一个基类,那么还是让它不可以继承吧。 例3:
| using namespace System; /*1*/ public ref class Deposit sealed : Transaction { /*2*/ Decimal amount; int toAccount; public: /*3a*/ Deposit(double amount, int toAccount) : Transaction(TransactionType::Deposit) { DepositAmount = Decimal(amount); DepositToAccount = toAccount; } /*3b*/ Deposit(Decimal amount, int toAccount) : Transaction(TransactionType::Deposit) { DepositAmount = amount; DepositToAccount = toAccount; } property Decimal DepositAmount { Decimal get() { return amount; }; private: void set(Decimal value) { amount = value; } } property int DepositToAccount { int get() { return toAccount; }; private: void set(int value) { toAccount = value; } } /*4*/ void PostTransaction() { Console::WriteLine("{0} -- {1}", DateTimeOfTransaction, this); } virtual String^ ToString() override { /*5*/ return String::Format(" Dep: {0,10:0.00} {1,10}",DepositAmount, DepositToAccount); } }; |
CLI只支持单一继承,因此,值类和引用类只能有一个直接的基类,默认情况下为System::Object。在标号1中,Deposit直接继承自Transaction,请注意没有public访问限定符,CLI只支持公有(public)继承,所以在此也可写为": public Transaction",但这是多余的。(对本地类而言,当继承的类型为结构struct时,默认为公有继承;当继承的类型为类class时,默认为私有继承。)
别忘了,CLI库支持一种非常适合金融计算的类型--System::Decimal,可在标号2中用它来表示存款额。
为了方便,提供了两个构造函数:一个接受表示为Decimal的数额,而另一个接受表示为double的数额。请注意,在两个构造函数的定义中,是怎样使用CLI enum作用域符来访问枚举器TransactionType中Deposit的。
为完成抽象基类,需提供标号4中的PostTransaction的实现,DateTime是一个值类型,因此当它的一个实例被传递进来时,它被装箱以匹配WriteLine所期望的Object^,而this表达式类型为Deposit^,其也继承自Object^。在这两种情况中,继承层次会一直往下,直到抵达并调用对应的ToString函数。
也能把函数PostTransaction声明为sealed,这样它就不能被覆盖了,然而,如果父类本身已经为sealed,那么函数永远也不可能被覆盖。
标号5中的格式指定符{0,10:0.00},表明在10个打印位宽度中右对齐数额,并四舍五入到小数点后两位,且至少在小数点前有一位数。

