类的继承(重写)

  • 类成员的”横向扩展”:成员越来越多(上小节)
  • 类成员的”纵向扩展”:行为改变,版本增高(即重写)
  • 类成员的隐藏(工作中是需要避免的,不常用)
  • 重写与隐藏的发生条件:函数成员(方法/属性),可见(访问级别为public/protected),签名一致
    • 重写的函数成员具体可以为以下:

image.png

  • 示例:子类成员对父类成员的重写,父类成员用virtual修饰,子类成员用override修饰 ```csharp using System;

namespace OverrideExample { class Program { static void Main(string[] args) { Car car = new Car(); car.Run();//输出:Car is running!

  1. Vehicle v = new Vehicle();
  2. v.Run();//I'm running!
  3. Vehicle v1 = new Car();//Is a
  4. v1.Run();//输出:Car is running!
  5. }
  6. }
  7. class Vehicle
  8. {
  9. public virtual void Run()
  10. {
  11. Console.WriteLine("I'm running!");
  12. }
  13. }
  14. class Car : Vehicle
  15. {
  16. public override void Run()
  17. {
  18. Console.WriteLine("Car is running!");
  19. }
  20. }

}


   - 如果父类成员不加virtual,子类成员不加override,则表示子类成员对父类成员的隐藏
   - 隐藏时Car类中有两个Run方法,一个this的Run,一个base的Run(继承父类的)
   - 隐藏时Vehicle v1 = new Car();   v1.Run();输出I'm running!,而重写则Car类中只有一个版本的Run方法
- 示例:继续增加派生类,引申多态概念,父类类型的变量引用子类类型的实例
```csharp
using System;

namespace OverrideExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Vehicle v = new RaceCar();//多态
            v.Run();//输出:RaceCar is running!
        }
    }

    class Vehicle
    {
        public virtual void Run()
        {
            Console.WriteLine("I'm running!");
        }
    }

    class Car : Vehicle
    {
        public override void Run()
        {
            Console.WriteLine("Car is running!");
        }
    }

    class RaceCar : Car
    {
        public override void Run()
        {
            Console.WriteLine("RaceCar is running!");
        }
    }
}
  • 如果RaceCar的Run方法不写override修饰,则RaceCar类中有2个版本的Run方法,一个是自身的,一个是Car版本的
  • 当Vehicle v = new RaceCar()时,变量v会顺着继承链向下找到Car时,Run不在向下重写,所以输出的结果为Car is running!,若想输出RaceCar is running!,则需改成RaceCar rc = new RaceCar()

多态

  • 基于重写机制(virtual -> override)
  • 函数成员的具体行为(版本)由对象决定
  • 属性也是method member,所以也能重写
  • 示例:属性的重写 ```csharp using System;

namespace OverrideExample { class Program { static void Main(string[] args) { Vehicle v = new Car(); v.Run();//输出:Car is running! Console.WriteLine(v.Speed);///输出:50 } }

class Vehicle
{
    private int _speed;

    public virtual int Speed
    {
        get { return _speed; }
        set { _speed = value; }
    }

    public virtual void Run()
    {
        Console.WriteLine("I'm running!");
        _speed = 100;
    }
}

class Car : Vehicle
{
    private int _rpm;

    public override int Speed
    {
        get { return _rpm / 100; }
        set { _rpm = value * 100; }
    }

    public override void Run()
    {
        Console.WriteLine("Car is running!");
        _rpm = 5000;
    }
}

} ```