1. 继承的核心定义
继承 是面向对象编程(OOP)的核心特性之一,允许一个类(称为子类/派生类)基于另一个类(称为父类/基类)构建,自动获得父类的成员(字段、属性、方法等),并可通过扩展或修改实现代码复用和多态行为。
2. C# 继承的关键特性
特性 | 说明、 |
---|---|
单继承 | C# 只支持单类继承(一个类只能有一个直接基类) |
接口多继承 | 一个类可实现多个接口(class A : I1, I2, I3) |
传递性 | 继承关系可多层传递(如 A → B → C) |
隐式继承 | 所有类隐式继承 System.Object(除非显式指定其他基类) |
成员可见性控制 | 通过 public、protected、private 等修饰符控制继承成员的访问权限 |
3. 继承的语法
// 基类定义
public class Vehicle
{public string Brand { get; set; }public void Start() => Console.WriteLine("Engine started");
}// 派生类继承基类
public class Car : Vehicle
{public int Wheels { get; set; }public void Drive() => Console.WriteLine("Driving...");
}
4. 继承的核心操作
(1) 访问基类成员
var car = new Car();
car.Brand = "Toyota"; // 继承自 Vehicle
car.Start(); // 调用基类方法
(2) 重写方法(虚方法)
public class Animal
{public virtual void Speak() => Console.WriteLine("Animal sound");
}public class Dog : Animal
{public override void Speak() => Console.WriteLine("Woof!");
}
(3) 抽象类与强制实现
public abstract class Shape
{public abstract double Area(); // 抽象方法(必须实现)
}public class Circle : Shape
{public double Radius { get; set; }public override double Area() => Math.PI * Radius * Radius;
}
5. 构造函数与继承
(1) 基类构造函数调用
public class BaseClass
{public BaseClass(int value) { /* 初始化逻辑 */ }
}public class DerivedClass : BaseClass
{// 必须通过 base 调用基类构造函数public DerivedClass(int value, string name) : base(value){Name = name;}public string Name { get; }
}
(2) 默认构造函数行为
若基类没有无参构造函数,派生类必须显式调用基类的有参构造函数,否则编译错误。
6. 阻止继承
使用 sealed 关键字禁止其他类继承:
public sealed class FinalClass { } // 不可被继承
public class InvalidDerived : FinalClass { } // 编译错误
# 7. 继承与多态
通过继承实现运行时多态性:
Animal animal = new Dog();
animal.Speak(); // 输出 "Woof!"(实际调用 Dog 类的方法)
8. 继承 vs 接口
场景 | 类继承 | 接口实现 |
---|---|---|
成员类型 | 可继承字段、方法、属性等具体实现 | 仅定义方法/属性签名(无实现) |
复用代码 | 直接复用基类逻辑 | 需重新实现所有接口成员 |
设计目标 | 表达 “is-a” 关系(如 Car 是 Vehicle) | 表达 “can-do” 能力(如 IDisposable) |
9. 最佳实践
-
避免深度继承链
超过 3 层的继承关系通常意味着设计问题,优先使用组合(has-a)而非继承(is-a)。 -
里氏替换原则(LSP)
子类必须能够完全替代基类,不破坏原有逻辑。 -
开放封闭原则(OCP)
通过继承扩展功能,而非修改基类代码。
10. 典型应用场景
- UI控件框架:Button、TextBox 继承自 Control 基类
- 领域模型:Employee、Manager 继承自 Person 基类
- 插件系统:通过基类定义插件接口,子类实现具体功能
通过合理使用继承,可以显著提升代码的可维护性和扩展性,但需谨慎避免过度设计。