多态性不仅对派生类很重要,对基类也很重要。任何情况下,使用基类实际上都可能是在使用已强制转换为基类类型的派生类对象。
当派生类从基类继承时,它会获得基类的所有方法、字段、属性和事件。面向对象的语言使用虚方法表达多态。
若要更改基类的数据和行为,您有两种选择:可以使用新的派生成员替换基成员,或者可以重写虚拟的基成员。
使用新的派生成员替换基类的成员需要使用 new 关键字。如果基类定义了一个方法、字段或属性,则 new 关键字用于在派生类中创建该方法、字段或属性的新定义。new 关键字放置在要替换的类成员的返回类型之前
使用 new 关键字时,调用的是新的类成员而不是已被替换的基类成员
class Gun
{
//瞄准
public void Loaded() {
Console.WriteLine("开枪前要瞄准!");
}
//开枪
public virtual void Fire() {
Console.WriteLine("嘣!!");
}
}
class AK47 : Gun
{
public new void Loaded() {
Console.WriteLine("AK47还需要瞄准?");
}
//重写父类中的开枪的方法
public override void Fire()
{
Console.WriteLine("Ak47,哒哒哒哒哒哒....");
}
}
class M16 : Gun {
public override void Fire()
{
Console.WriteLine("M16,啪啪啪啪....");
}
}
字段不能是虚拟的,只有方法、属性、事件和索引器才可以是虚拟的。当派生类重写某个虚拟成员时,即使该派生类的实例被当作基类的实例访问,也会调用该成员
使用虚拟方法和属性可以预先计划未来的扩展。由于在调用虚拟成员时不考虑调用方正在使用的类型,所以派生类可以选择完全更改基类的外观行为。
无论在派生类和最初声明虚拟成员的类之间已声明了多少个类,虚拟成员都将永远为虚拟成员。如果类 A 声明了一个虚拟成员,类 B 从 A 派生,类 C 从类 B 派生,则类 C 继承该虚拟成员,并且可以选择重写它,而不管类 B 是否为该成员声明了重写。
派生类可以通过将重写声明为密封的来停止虚拟继承。这需要在类成员声明中将 sealed 关键字放在 override 关键字的前面
建议虚拟成员在它们自己的实现中使用 base 来调用该成员的基类实现。允许基类行为发生使得派生类能够集中精力实现特定于派生类的行为。未调用基类实现时,由派生类负责使它们的行为与基类的行为兼容。
public virtual void AttackMethod() {
Console.WriteLine("英雄{0}攻击了一次",this.h_name);
}
}
class ADC : Hero {
public override void AttackMethod()
{
base.AttackMethod();
Console.WriteLine("英雄{0}使用万箭齐发技能",this.h_name);
Console.WriteLine("射手触发了暴击被动!");
}
}