什么是多态:
父类的一些成员,子类继承周去重写从而实现不同的功能。
多态的风雷
多态分为两种,一种是编译时的多态,一种是运行时的多态。
编译时多态:编译时的多态性是通过重载来实现的。
编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。
运行时的多态性:运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。C#中运行时的多态性是通过覆写虚成员实现。
多态的实现
重载(overload)
重载指的是同一个累中有两个或者多个名字但是参数不同的方法。
public void Calculate() { // do the calculation here } public void Calculate(int num) { // do the calculation here }
运行时多态: 重写
重写有两种, 一种是override修饰符, 另一种使用new 修饰符
override是指“覆盖”,是指子类覆盖了父类的方法。子类的对象无法再访问父类中的该方法。
new是指“隐藏”,是指子类隐藏了父类的方法,当然,通过一定的转换,可以在子类的对象中访问父类的方法。
重新(override)是对父类中的虚函数(virtual method)或抽象函数的“覆盖”。
/// <summary> /// 动物类(父类) /// </summary> class Animal { /// <summary> /// 名字 /// 说明:类和子类可访问 /// </summary> protected string name; /// <summary> /// 构造函数 /// </summary> /// <param name="name"></param> public Animal(string name) { this.name=name; } /// <summary> /// 名字(虚属性) /// </summary> public virtual string MyName { get { return this.name; } } /// <summary> /// 吃(虚方法) /// </summary> public virtual void Eat() { Console.WriteLine("我会吃!"); } /// <summary> /// 叫(虚方法) /// </summary> public virtual void Shout() { Console.WriteLine("我会叫!"); } } /// <summary> /// 狗(子类) /// </summary> class Dog:Animal { string myName; public Dog(string name): base(name) { myName = name; } /// <summary> /// 名字(重写父类属性) /// </summary> public override string MyName { get { return "我是:狗狗,我叫:"+this.name; } } /// <summary> /// 吃(重写父类虚方法) /// </summary> public override void Eat() { Console.WriteLine("我喜欢吃肉!"); } /// <summary> /// 叫(重写父类方法) /// </summary> public override void Shout() { Console.WriteLine("汪!汪!汪!"); } } /// <summary> /// 猫(子类) /// </summary> class Cat : Animal { string myName; public Cat(string name) : base(name) { myName = name; } /// <summary> /// 名字(重写父类属性) /// </summary> public override string MyName { get { return "我是:猫咪,我叫:" + this.name; } } /// <summary> /// 吃(重写父类虚方法) /// </summary> public override void Eat() { Console.WriteLine("我喜欢吃鱼!"); } /// <summary> /// 叫(重写父类方法) /// </summary> public override void Shout() { Console.WriteLine("喵!喵!喵!"); } } /// <summary> /// 羊(子类) /// </summary> class Sheep : Animal { string myName; public Sheep(string name) : base(name) { myName = name; } /// <summary> /// 名字(重写父类属性) /// </summary> public override string MyName { get { return "我是:羊羊,我叫:" + this.name; } } /// <summary> /// 吃(重写父类虚方法) /// </summary> public override void Eat() { Console.WriteLine("我喜欢吃草!"); } /// <summary> /// 叫(重写父类方法) /// </summary> public override void Shout() { Console.WriteLine("咩!咩!咩!"); } }
重写(new)
new:隐藏从父类继承过来的同名成员。
隐藏的后果是子类调用不到父类的成员。
/// <summary> /// 动物类(父类) /// </summary> class Animal { /// <summary> /// 名字 /// 说明:类和子类可访问 /// </summary> protected string name; /// <summary> /// 构造函数 /// </summary> /// <param name="name"></param> public Animal(string name) { this.name=name; } /// <summary> /// 名字(虚属性) /// </summary> public virtual string MyName { get { return this.name; } } /// <summary> /// 吃(虚方法) /// </summary> public virtual void Eat() { Console.WriteLine("我会吃!"); } /// <summary> /// 叫(虚方法) /// </summary> public virtual void Shout() { Console.WriteLine("我会叫!"); } } /// <summary> /// 狗(子类) /// </summary> class Dog:Animal { string myName; public Dog(string name): base(name) { myName = name; } /// <summary> /// 名字(重写父类属性) /// </summary> public override string MyName { get { return "我是:狗狗,我叫:"+this.name; } } /// <summary> /// 吃(重写父类虚方法) /// </summary> new public void Eat() { Console.WriteLine("我喜欢吃肉!"); } /// <summary> /// 叫(重写父类方法) /// </summary> public new void Shout() { Console.WriteLine("汪!汪!汪!"); } }