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