第 4 章 继 承
{
public int MyGroovyMethod()
{
// some groovy implementation
return 0;
}
}
一年后,基类的编写者决定扩展基类的功能。为了 保持一致,他也添加了一个名为
MyGroovyMethod()的方法,该方法的名称和签名与前面添加的方法相同,但并不完成相同的工
作。在使用基类的新方法编译代码时,程序在应该调用哪个方法上就会有潜在的冲突。这在C#
中完全合法,但因为我们的MyGroovyMethod()与基类的MyGroovyMethod()不相关,运行这段代
码的结果就可能不是我们希望的结果。C#已经为此设计了一种方式,可以很好地处理这种情况
首先,系统会发出警告。在C#中,应使用new关键字声明我们要隐藏一个方法,如下所示:
class MyDerivedClass : HisBaseClass
{
public new int MyGroovyMethod()
{
// some groovy implementation
return 0;
}
}
但是,我们的MyGroovyMethod()没有声明为new,所以编译器会认为它隐藏了基类的方法,
但没有显式声明,因此发出一个警告(这也适用于把MyGroovyMethod()声明为 virtual)。如果愿意
可以给我们的方法重命名。这么做,是最好的情形,因为这会避免许多冲突。但是,如果觉得重
命名方法是不可能的(例如,已经为其他公司把软件发布为一个库,所以无法修改方法的名称),
则所有的已有客户机代码仍能正确运行,选择我们的MyGroovyMethod()。这是因为访问这个方
法的已有代码必须通过对MyDerivedClass(或进一步派生的类)的引用进行选择。
已有的代码不能通过对HisBaseClass的引用访问这个方法,因为在对HisBaseClass的早期版
本进行编译时,会产生一个编译错误。这个问题只会发生在将来编写的客户机代码上。C#会发
出一个警告,告诉用户在将来的代码中可能会出问题——用户应注意这个警告,不要试图在将来
的代码中通过对HisBaseClass的引用调用MyGroovyMethod()方法,但所有已有的代码仍会正常工
作。这是比较微妙的,但很好地说明了C#如何处理类的不同版本。
4.2.3 调用函数的基类版本
C#有一种特殊的语法用于从派生类中调用方法的基类版本:base.<MethodName>()。例如,
假定派生类中的一个方法要返回基类的方法返回的值的90%,就可以使用下面的语法:
class CustomerAccount