继承与多态

翻译整理自 Inheritance 与 Polymorphism。

1. 基类与派生类

C# 单继承:

public class Animal
{
    public string Name { get; set; }
    public virtual void Speak() => Console.WriteLine("...");
}

public class Dog : Animal
{
    public override void Speak() => Console.WriteLine("Woof");
}

public class Cat : Animal
{
    public override void Speak() => Console.WriteLine("Meow");
}

Animal a = new Dog();
a.Speak();                  // Woof

2. virtual / override

virtual 标记可覆盖,override 显式覆盖:

public class Base
{
    public virtual void F() => Console.WriteLine("Base.F");
}

public class Derived : Base
{
    public override void F() => Console.WriteLine("Derived.F");
}

3. sealed

public sealed class FinalClass { }            // 不能被继承

public class B : Base
{
    public sealed override void F() { }       // 不能再被覆盖
}

4. abstract 抽象类与方法

public abstract class Shape
{
    public abstract double Area();            // 抽象方法
    public virtual void Print() => Console.WriteLine(Area());
}

public class Circle(double r) : Shape
{
    public override double Area() => 3.14 * r * r;
}

// Shape s = new Shape();    // ❌ 抽象类不能实例化
Shape s = new Circle(1);

5. base 调用基类

public class Base
{
    public virtual void F() => Console.WriteLine("Base");
}

public class D : Base
{
    public override void F()
    {
        base.F();
        Console.WriteLine("D");
    }
}

6. 构造顺序

基类构造先于派生类:

public class Animal
{
    public Animal() => Console.WriteLine("Animal ctor");
}

public class Dog : Animal
{
    public Dog() => Console.WriteLine("Dog ctor");
}

new Dog();
// Animal ctor
// Dog ctor

调用基类带参构造:

public class Animal(string name)
{
    public string Name { get; } = name;
}

public class Dog(string name, string breed) : base(name)
{
    public string Breed { get; } = breed;
}

7. 隐藏方法 new

public class Base { public void F() { } }
public class D : Base { public new void F() { } }   // 显式隐藏,不要 override

隐藏与多态冲突,应优先 virtual/override。

8. object 与 ToString

所有类型继承自 System.Object:

public class Person
{
    public override string ToString() => $"{Name}({Age})";
}

9. 类型检查

Animal a = new Dog();

if (a is Dog d) d.Speak();

if (a is Dog) { }

C# 7+ 模式:

switch (a)
{
    case Dog d: d.Speak(); break;
    case Cat c: c.Speak(); break;
    case null: throw new ArgumentNullException();
}

10. 多态示例

List<Animal> zoo = new() { new Dog(), new Cat(), new Dog() };
foreach (var a in zoo)
    a.Speak();

小结

C# 单继承 + 接口设计清晰,virtual/override/abstract 是多态三件套。