C# 中覆盖(override)的概念及基本用法

在C#中,覆盖(override)是面向对象编程中实现多态性的核心机制,允许子类重写基类的方法、属性或索引器。以下是关键点总结:

1. ​覆盖的基本用法

  • 基类方法:使用 virtualabstract 或已标记为 override 的方法。
  • 子类方法:使用 override 关键字重写基类方法。
 
  

csharp

public class Animal {
    public virtual void MakeSound() => Console.WriteLine("Animal sound");
}

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

2. ​覆盖 vs 隐藏(new 关键字)​

  • 覆盖:通过基类引用调用时,实际执行子类的方法(动态绑定)。
  • 隐藏:通过基类引用调用时,执行基类的方法(静态绑定)。
 
  

csharp

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

// 使用示例:
Animal animal = new Dog();
animal.MakeSound(); // 输出 "Bark"(覆盖)

Animal cat = new Cat();
cat.MakeSound();    // 输出 "Animal sound"(隐藏)

3. ​抽象方法强制覆盖

  • 基类标记为 abstract 的方法必须由子类实现,且必须使用 override
 
  

csharp

public abstract class Shape {
    public abstract double Area();
}

public class Circle : Shape {
    public override double Area() => Math.PI * Radius * Radius;
}

4. ​覆盖的规则

  • 签名一致:方法名、返回类型、参数列表必须与基类一致。
  • 访问修饰符:子类方法的访问级别不能比基类更严格(例如,基类为 protected,子类不能为 private)。
  • 密封覆盖:使用 sealed override 阻止进一步覆盖。
 
  

csharp

public class AdvancedDog : Dog {
    public sealed override void MakeSound() => Console.WriteLine("Loud bark");
}

5. ​覆盖属性与索引器

  • 属性(Property)和索引器(Indexer)也可以被覆盖。
 
  

csharp

public class Vehicle {
    public virtual int Wheels => 4;
}

public class Bike : Vehicle {
    public override int Wheels => 2;
}

6. ​常见错误与注意事项

  • 未标记 virtual:基类方法未标记为 virtual 或 abstract,子类无法覆盖。
  • 混淆 override 和 new:错误使用 new 导致隐藏而非覆盖。
  • 静态方法:静态方法不能覆盖,但可用 new 隐藏。
 
  

csharp

public class Base {
    public static void StaticMethod() { }
}

public class Derived : Base {
    public new static void StaticMethod() { } // 隐藏基类静态方法
}

总结

  • 覆盖(override)​ 实现运行时多态,根据对象实际类型调用方法。
  • 隐藏(new)​ 仅隐藏基类成员,不影响虚方法表。
  • 使用 virtualabstract 和 override 明确多态行为,避免混淆。

你可能感兴趣的:(C#,开发语言,c#,开发语言)