练习
(1)下述哪些项在 OOP 中有真实级别的可访问性? ● 友元
● 公共
● 安全
● 私有
● 受保护的
● 松散的
● 通配符
答案:B、D和E。public、private和protected是实际的可访问级别。
(2)“必须手动调用对象的析构函数,否则就会浪费内存”的说法正确吗?
答案:错误,永远都不应手工调用对象的析构函数,.NET运行库环境会在垃圾回收过程中自动完成该任务。
(3)在调用类的静态方法时,需要创建该类的对象吗?
答案:不,可以在没有任何类实例的情况下调用静态方法。
(4)为下述类和接口绘制一个类似于本章介绍的图形的 UML 图:
● 抽象类 HotDrink
,它具有方法 Refill
和 Wash
,以及属性 Color
和 Volume
。
● 接口 Icup
,它具有方法 Refill
和 Wash
,以及属性 Color
和 Volume
。 ● 派生于 HotDrink
的类 CupOfCoffee
支持 ICup
接口,还有一个属性 BeanType
。
● 派生于 HotDrink
的类 CupOfCoffee
支持 ICup
接口,还有一个属性 LeafType
。
答案:
(5)为一个函数编写一些代码,接受上述示例的两个杯子对象中的任意一个作为参数。该函数应该为传递给它的任何杯子对象调用 AddMilk
、Drink
和 Wash
方法。
答案:
static void ManipulateDrink(HotDrink drink)
{
drink.AddMilk();
drink.Drink();
ICup cupInterface = (ICup)drink;
cupInterface.Wash();
}
注意显式转换为ICup的代码行。这是必需的,因为HotDrink不支持ICup接口,但我们知道传送给这个函数的两个cup对象支持ICup接口。这很危险,因为也可以给这个函数传送其他类,但这些类也可能派生于HotDrink,而HotDrink却不支持ICup接口。为了更正这个问题,应检查该接口是否得到支持:
static void ManipulateDrink(HotDrink drink)
{
drink.AddMilk();
drink.Drink();
if(drink is ICup)
{
ICup cupInterface = (ICup)drink;
cupInterface.Wash();
}
}
这里使用的is和as操作符在第11章介绍。