类的继承 (Class Inheritance)
类的继承是面向对象编程 (OOP) 的三大特性之一(封装、继承、多态)。它允许我们定义一个类(子类/派生类)来继承另一个类(父类/基类)的特性和行为。
1. 基本语法与概念
在 C# 中,继承使用冒号 ``:`` 符号。
格式:
class 子类名 : 父类名 { // 子类特有的成员 }
核心规则: * 单继承原则 (Single Inheritance): 一个类只能直接继承一个父类(即 ``PS:单个类只能继承一个类!``)。但一个类可以实现多个接口。 * 继承的本质: 子类会自动拥有父类中所有非私有 (non-private) 的成员(字段、属性、方法)。这实现了代码的复用。 * 传递性: 如果 A 继承 B,B 继承 C,那么 A 同时拥有 B 和 C 的成员。
2. 基础实例分析
以下代码展示了如何通过继承共享属性 ``A``,同时子类各自拥有独立的成员。
using System; namespace InheritanceDemo { class Program { static void Main(string[] args) { // 1. 实例化子类 wlala wlala hei = new wlala(); // 2. 实例化子类 Bsei Bsei kar = new Bsei(); // 3. 访问继承自父类 FB1 的属性 A hei.A = 69; // wlala 本身没有定义 A,是继承来的 kar.A = 32; // Bsei 同理 // 4. 执行子类特有的方法 hei.beis(); // 输出: 69 // kar.beis(); // 报错:Bsei 类中没有 beis 方法 } } // ==== 父类 (基类) ==== class FB1 { // 所有子类都会拥有的属性 public int A { get; set; } } // ==== 子类 1 ==== // wlala 继承了 FB1,所以它拥有 A class wlala : FB1 { public int B { get; set; } // 子类特有的属性 public void beis() // 子类特有的方法 { // 可以直接访问父类的 A Console.WriteLine("从父类继承的 A = {0}", A); } } // ==== 子类 2 ==== class Bsei : FB1 { public int C { get; set; } } }
3. 继承的核心思想与多态
继承不仅仅是为了少写代码,更重要的是为了实现多态 (Polymorphism) 和里氏替换原则 (LSP)。
3.1 核心思想 1:复用
- 子类可以使用父类成员: 避免了在 ``wlala`` 和 ``Bsei`` 中重复定义属性 ``A``。修改父类的逻辑,所有子类都会自动更新。
3.2 核心思想 2:多态与里氏替换
- 概念: 父类类型的变量可以引用子类的实例。
- 应用场景: 工厂模式、依赖注入、统一处理集合。
代码修正与深度解析: 原笔记中的 ``public void shengcan();`` 是错误的语法。在类中,普通方法必须有方法体 ``{}``。如果想只定义规范而不实现,必须使用 ``abstract`` (抽象类) 或 ``interface`` (接口)。
以下是修正后的工厂模式/多态示例:
using System; namespace FactoryPatternDemo { class Program { static void Main(string[] args) { // 声明一个父类变量 nb NoteBook nb = null; // 【多态的核心】:父类变量指向子类对象 // 无论 new 出来的是 Lenovo 还是 IBM,它们都是 NoteBook nb = new Lenovo(); nb.ShengCan(); // 调用的是 Lenovo 的生产逻辑 nb = new IBM(); nb.ShengCan(); // 调用的是 IBM 的生产逻辑 // 实际应用中,这里通常配合简单工厂模式: // NoteBook myComputer = ComputerFactory.Create("Lenovo"); } } // 建议将父类定义为 abstract (抽象类),因为单纯的 "笔记本" 概念无法生产, // 只有具体的品牌才能生产。 public abstract class NoteBook { // 抽象方法:强制子类必须实现这个方法 public abstract void ShengCan(); } // 以下类继承了 NoteBook 父类 public class Lenovo : NoteBook { public override void ShengCan() { Console.WriteLine("联想笔记本正在生产..."); } } public class IBM : NoteBook { public override void ShengCan() { Console.WriteLine("IBM ThinkPad 正在生产..."); } } public class Weixing : NoteBook // 微星 { public override void ShengCan() { Console.WriteLine("微星游戏本正在生产..."); } } public class DeLL : NoteBook { public override void ShengCan() { Console.WriteLine("戴尔笔记本正在生产..."); } } }
4. 知识点扩展 (Deep Dive)
为了更深入理解继承,需要注意以下几点:
- 访问修饰符 (Access Modifiers):
- ``public``: 子类和外部都能访问。
- ``private``: 只有父类自己能访问,子类无法直接访问(虽然继承了,但不可见)。
- ``protected``: 关键修饰符。只有父类和子类可以访问,外部无法访问。
- 构造函数 (Constructors):
- 构造函数不会被继承。
- 实例化子类时,会先执行父类的构造函数,再执行子类的构造函数。
- 如果父类构造函数需要参数,子类必须使用 ``: base(参数)`` 显式调用。
- Object 类:
- 在 C# 中,所有的类都隐式继承自 ``System.Object`` 类。因此所有类都有 ``ToString()``, ``Equals()`` 等方法。