只有基类成员声明为virtual或abstract时,才能被派生类重写;而如果子类想改变虚方法的实现行为,则必须使用override关键字。
public class Animal { private int _age; public int Age { get { return _age; } set { //这里假设牛的寿命为10年。 if(value <0 ||value >10) { throw (new ArgumentOutOfRangeException("AgeIntPropery", value, "年龄必须在0-10之间")); } _age = value; } } //几乎所有动物都具备发出声音的能力 /// <summary> /// 但是对于动物来说,每个动物发出的声音都不一样 /// </summary> public virtual void Voice() { Console.WriteLine("动物开始发出声音"); } //马(子类) public class Horse:Animal { //通过override关键字来重写父类方法 public override void Voice() { base.Voice(); Console.WriteLine("马儿发出嘟...嘟....嘟....的声音"); } } //羊 (子类) public class Sheep:Animal { public override void Voice() {
//调用基类方法 base.Voice(); Console.WriteLine("羊发出咩...咩...咩...的声音"); } }
static void Main(string[] args) { Animal horse = new Horse(); horse.Voice(); Animal sheep = new Sheep(); //相同类型的对象调用相同的方法表现出不同的行为 sheep.Voice(); Console.Read(); }
通过使用virtual关键字,把需要在子类中表现为不同行为的方法定义为虚方法,然后在子类中使用override关键字对基类方法进行重写。这样,每个基类在调
用相同的方法时将表现出不同的行为,这段代码正是c#中多态的实现。
若子类还想继续访问基类定义的方法,则可以使用Base关键字来完成调用。
如图运行结果可以看出,相同类型的对象调用相同的方法确实表现了不同的行为,这就是多态的精髓所在。
但是,上面的代码还存在一个问题;我们可以通过new操作符创建Animal基类的实例,可Animal基类的作用是为所有子类提供公共成员,它是一个
抽象的概念,在实际的系统中我们希望能避免创建该类的实例。该怎么做?
对应c#,可以使用abstract关键字来防止在代码中直接创建这样的类的实例,如下:
public abstract class Animal { ..... }
酱紫 ,若尝试创建Animal实例,就会收到如下所示报错。