什么是多态性?
概念:同一个操作对于不同的操作对象,可以有不同的解释,并产生不同的执行结果。
多态类通过派生类覆盖基类中的虚函数型方法实现。
形式:编译时的多态;运行时的多态。
编译时的多态:编译时的多态通过重载来实现。它可能从参数中获取的信息不同,也可能是返回的类型不同。
运行时的多态:运行时的多态必须通过覆盖基类来实现。
重载:在一个类中,具有相同方法名的方法。
public int math(int x,int y);
public int math(int x,int y,int z);
public int math(double x,double y);
public double math(double x,double y);
特征是:主要是参数的类型和个数不同(必须)
方法名必须相同
返回类型可以相同,可以不同
覆盖:子类为了满足自己的需要,而重新定义这个方法,只是对方法实现体的修改.所以:
要求:
方法名必须相同
参数类型个数必须相同
返回类型必须相同
关键字:override
什么方法可以覆盖?
只有虚方法和抽象方法可以覆盖。
虚方法:
关键字:virtual
方法调用时,先调用本类中的该方法,没有再调用基类中的虚方法。
虚方法可以有实现体。
抽象方法:
关键字:abstract
当类中有抽象方法时,类必须是抽象类型。
抽象方法一定没有实现体。
长久以来,多态性一直困扰着我,虽然我知道是怎么回事,但说不出来,也许就是只能意会,不能言传吧,
通过继承,一个类可以用作多种类型 :可以用作它自己的类型,也可以用作基类型,或者在实现接口时用作任何接口类型,这就成为多态性。
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; }
}
}
字段不能是虚拟的,只有方法、属性、事件和索引器才可以是虚拟的。当派生类重写某个虚拟成员时,即使该派生类的实例被当作基类的实例访问,也会调用该成员
使用虚拟方法和属性可以预先计划未来的扩展。由于在调用虚拟成员时不考虑调用方正在使用的类型,所以派生类可以选择完全更改基类的外观行为。
无论在派生类和最初声明虚拟成员的类之间已声明了多少个类,虚拟成员都将永远为虚拟成员
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/meifage9/archive/2011/06/16/6548754.aspx