长久以来,多态性一直困扰着我,虽然我知道是怎么回事,但说不出来,也许就是只能意会,不能言传吧,
通过继承,一个类可以用作多种类型 :可以用作它自己的类型,也可以用作基类型,或者在实现接口时用作任何接口类型,这就成为多态性。
C# 中每种类型都是多态的,类型可用作他们自己的类型或用作Object的实例,因为任何类型都自动将Object当作基类型。
多态性不仅对派生类很重要,对基类也很 重要,在任何情况下,使用基类实际上是都可能是在使用已经强制转化成基类类型的派生类对象,基类的设计者预测到其基类中可能会在派生类中发生更改的方面。
当派生类从基类继承时,它会获得所有基类的方法,属性等,若要改变基类的和行为,有两种方法:一是使用新的派生成员替代基成员,二是重写基类中的虚拟成员。
使用新的派生成员替换基成员使用关键字new,如果基类定义了一个方法或字段,则new关键字创建该方法或字段的新定义,new关键字要放在返回值类型之前。
如:
class BaseClass
{
public void BaseMethod()
{ }
}
class DerivedClass : BaseClass
{
public new void BaseMethod()
{ }
}
使用 new 关键字时,调用的是新
的类成员而不是已被替换的基类成员。这些基类成员称为隐藏成员。如果将派生类的实例强制转换为基类的实例,就仍然可以调用隐藏类成员。
为了使派生类的实例完全接替来自基类的类成员,基类必须将该成员声明为虚拟的。这是通过在该成员的返回类型之前添加 virtual 关键字来实现的。然后,派生类可以选择使用 override 关键字而不是 new,将基类实现替换为它自己的实现。
如:
public class BaseClass
{
public virtual int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public override int WorkProperty
{
get { return 0; }
}
}
字段不能是虚拟的,只有方法、属性、事件和索引器才可以是虚拟的。当派生类重写某个虚拟成员时,即使该派生类的实例被当作基类的实例访问,也会调用该成员
使用虚拟方法和属性可以预先计划未来的扩展。由于在调用虚拟成员时不考虑调用方正在使用的类型,所以派生类可以选择完全更改基类的外观行为。
无论在派生类和最初声明虚拟成员的类之间已声明了多少个类,虚拟成员都将永远为虚拟成员