继承(Inheritance)是 C# 面向对象编程(OOP)的核心特性之一,它允许一个类获得另一个类的成员(字段、属性、方法等),从而实现代码复用,并建立类之间的层次关系。
简单理解:
子类(派生类)继承父类(基类)的特征,并可以扩展或修改这些特征。
例如:
- 动物 → 狗
- 交通工具 → 汽车
- 员工 → 程序员
这些关系都符合:
狗是一种动物
汽车是一种交通工具
程序员是一种员工
在 C# 中通常称为is-a 关系。
1. 基本语法
C# 使用冒号:表示继承。
语法:
class 子类 : 父类 { }例如:
// 父类 class Animal { public string Name; public void Eat() { Console.WriteLine("动物吃东西"); } } // 子类继承 Animal class Dog : Animal { }使用:
Dog dog = new Dog(); dog.Name = "旺财"; dog.Eat();输出:
动物吃东西虽然Dog没有定义Eat()方法,但是继承了Animal的方法。
2. 继承获得什么?
子类可以继承父类:
| 成员 | 是否继承 |
|---|---|
| public 字段 | ✅ |
| public 属性 | ✅ |
| public 方法 | ✅ |
| protected 成员 | ✅ |
| private 成员 | ❌ |
| 构造函数 | ❌ |
| 析构函数 | ❌ |
例如:
class Person { public string Name; protected int Age; private string Password; public void Speak() { Console.WriteLine("说话"); } } class Student : Person { }Student:
可以访问:
Name; Age; Speak();不能访问:
Password;3. 父类和子类关系
例如:
class Animal { public void Eat() { Console.WriteLine("吃东西"); } } class Cat : Animal { public void CatchMouse() { Console.WriteLine("抓老鼠"); } }调用:
Cat cat = new Cat(); cat.Eat(); cat.CatchMouse();输出:
吃东西 抓老鼠结构:
Animal | | CatCat 拥有:
Eat() CatchMouse()4. 子类扩展父类功能
继承最大的作用:
在已有功能基础上增加新功能。
例如:
class Employee { public string Name; public void Work() { Console.WriteLine("工作"); } } class Programmer : Employee { public void WriteCode() { Console.WriteLine("写代码"); } }使用:
Programmer p = new Programmer(); p.Name = "张三"; p.Work(); p.WriteCode();输出:
工作 写代码5. 方法重写(override)
继承后,有时候子类需要改变父类的方法行为。
这叫:
方法重写(Override)
父类:
class Animal { public virtual void Sound() { Console.WriteLine("动物叫"); } }注意:
virtual
表示:
这个方法允许子类修改。
子类:
class Dog : Animal { public override void Sound() { Console.WriteLine("汪汪叫"); } }调用:
Animal a = new Dog(); a.Sound();输出:
汪汪叫6. virtual 和 override
继承中常见组合:
父类
public virtual 方法()允许修改。
子类
public override 方法()重新实现。
例如:
class Shape { public virtual void Draw() { Console.WriteLine("画图形"); } } class Circle : Shape { public override void Draw() { Console.WriteLine("画圆"); } }7. base 关键字
base表示:
调用父类成员
例如:
class Animal { public void Eat() { Console.WriteLine("吃东西"); } } class Dog : Animal { public void Eat() { base.Eat(); Console.WriteLine("狗吃骨头"); } }调用:
Dog d = new Dog(); d.Eat();输出:
吃东西 狗吃骨头8. 调用父类构造函数
子类对象创建时:
一定会先调用父类构造函数。
例如:
class Person { public Person() { Console.WriteLine("Person构造"); } } class Student : Person { public Student() { Console.WriteLine("Student构造"); } }执行:
Student s = new Student();输出:
Person构造 Student构造顺序:
父类构造 ↓ 子类构造9. 使用 base 调父类构造
父类:
class Person { public Person(string name) { Console.WriteLine(name); } }子类:
class Student : Person { public Student() : base("学生") { } }执行:
Student s = new Student();输出:
学生10. C# 不支持多继承
C#:
❌ 不允许:
class Dog : Animal, Pet { }一个类只能继承一个父类。
但是支持多个接口:
✅
class Dog : Animal, IRunnable, IFlyable { }结构:
Animal | Dog / \ IRunnable IFlyable11. sealed 禁止继承
如果不希望别人继承你的类:
使用:
sealed例如:
sealed class MathHelper { }下面会报错:
class MyMath : MathHelper { }错误:
无法从密封类型继承12. 抽象类继承
抽象类:
不能直接创建对象。
例如:
abstract class Animal { public abstract void Sound(); }子类必须实现:
class Dog : Animal { public override void Sound() { Console.WriteLine("汪汪"); } }使用:
Animal a = new Dog(); a.Sound();13. 继承与多态
继承是多态的基础。
例如:
class Animal { public virtual void Speak() { Console.WriteLine("动物声音"); } } class Dog : Animal { public override void Speak() { Console.WriteLine("汪汪"); } } class Cat : Animal { public override void Speak() { Console.WriteLine("喵喵"); } }统一调用:
Animal[] animals = { new Dog(), new Cat() }; foreach(Animal a in animals) { a.Speak(); }输出:
汪汪 喵喵这就是:
父类引用指向不同子类对象。
14. 类型转换
向上转换(自动)
子类 → 父类
安全:
Dog dog = new Dog(); Animal animal = dog;向下转换(需要强制)
父类 → 子类
Animal animal = new Dog(); Dog dog = (Dog)animal;15. is 判断类型
if(animal is Dog) { Console.WriteLine("这是狗"); }16. as 转换
Dog dog = animal as Dog; if(dog != null) { dog.Sound(); }17. 继承实际案例
例如游戏开发:
父类:
class Character { public int HP; public virtual void Attack() { Console.WriteLine("攻击"); } }战士:
class Warrior : Character { public override void Attack() { Console.WriteLine("挥剑攻击"); } }法师:
class Mage : Character { public override void Attack() { Console.WriteLine("释放魔法"); } }调用:
Character c1 = new Warrior(); Character c2 = new Mage(); c1.Attack(); c2.Attack();输出:
挥剑攻击 释放魔法18. 继承设计原则
适合继承:
例如:
动物 | 狗因为:
狗 是 动物不适合继承:
例如:
汽车 | 发动机因为:
发动机不是汽车这种应该使用组合:
class Car { Engine engine; }19. 继承 vs 组合
| 特点 | 继承 | 组合 |
|---|---|---|
| 关系 | is-a | has-a |
| 代码复用 | 高 | 高 |
| 耦合 | 强 | 弱 |
| 灵活性 | 低 | 高 |
| 推荐程度 | 谨慎使用 | 优先考虑 |
现代 C# 开发中:
优先组合,谨慎继承。
20. C# 继承核心总结
| 关键字 | 作用 |
|---|---|
: | 表示继承 |
virtual | 允许重写 |
override | 重写父类方法 |
base | 访问父类 |
abstract | 抽象类/抽象方法 |
sealed | 禁止继承 |
protected | 给子类访问 |
is | 类型判断 |
as | 安全转换 |
一句话总结
C# 继承让子类复用父类代码,并通过 virtual + override 实现多态,是面向对象设计中实现扩展和复用的重要机制。
继承通常和封装、抽象、多态一起构成 C# 面向对象编程的四大核心思想。