c#中继承用:声明,但多态需virtual/override配合且调用须通过基类引用;private成员不可继承,构造函数须显式/隐式调用基类,struct不可继承类仅可实现接口。

直接说结论:C# 中用 : 符号声明继承,但继承本身不自动带来多态;必须配合 virtual / override 才能实现运行时多态。很多人写完 class Dog : Animal 就以为“多态成了”,结果调用时还是走基类逻辑——问题就出在这里。
怎么写继承语法(别漏掉访问修饰符和构造函数)
继承不是加个冒号就完事。C# 要求基类成员至少是 protected 或 public 才能被派生类访问;private 成员完全不可见。
-
class Dog : Animal语法合法,但若Animal.Name是private,Dog里就访问不到 - 派生类构造函数必须显式或隐式调用基类构造函数;没写
: base(...)时,编译器会插一句: base(),前提是基类有无参构造函数 - 如果基类只有带参构造函数(比如
Animal(string name)),派生类必须写public Dog() : base("unknown"),否则编译失败
为什么 new Dog().ToString() 还是输出 Object 的内容?
因为 ToString() 默认是 sealed 的非虚方法,除非你在基类里把它声明为 virtual,子类用 override 重写,否则不会触发多态分发。
- 错误写法:
public void ToString() { ... }—— 这是隐藏(new),不是重写,调用时看变量声明类型 - 正确写法:
public override string ToString() { return $"Dog: {Name}"; } - 验证是否生效:把
Dog实例赋给Animal变量,再调.ToString(),输出应是你重写的版本
多态生效的三个硬性条件
少一个,foreach (Animal a in list) 里调 a.DoSomething() 都不会走到子类实现。
- 基类方法必须标记为
virtual(或abstract) - 派生类方法必须用
override,不能用new - 调用必须通过基类引用(或接口引用),而不是直接用派生类类型变量
例如:Animal a = new Dog(); a.Move(); → 走 Dog.Move();但 Dog d = new Dog(); d.Move(); 即使加了 override,也只说明它支持多态,不等于这次调用就用了多态。
结构体(struct)不能继承类,但能实现接口
这是初学者常踩的坑:写 struct Point : Shape 会直接编译报错 CS0527: 'Point': structs cannot inherit from classes or other structs。
- 结构体只能
: IComparable, IDisposable这类接口,不能有基类 - 如果真需要类似“继承”的行为,得用组合:在 struct 里放一个
Shape引用字段,或改用class - 注意值类型语义:结构体拷贝时,内部引用字段也会被复制(浅拷贝),不是继承带来的共享语义
继承链越深,构造函数调用顺序、字段初始化时机、base 调用位置就越容易出错;真正要用多态,先确保虚方法链条从声明到调用全程可控,而不是靠猜。










