【C#学习Day12笔记】抽象类、密封类与子类构造(继承)
前言
在C#第12天的学习中,我深入探索了面向对象编程的高级特性:抽象类、密封类和子类构造机制。这些概念是构建健壮、可扩展软件系统的关键。本文完整保留我的课堂实践代码和命名体系,通过结构化梳理帮助大家掌握这些核心知识。所有代码示例均来自我的实际操作,包含了从理论到实践的完整过程!
一、抽象类与抽象方法:设计模板的利器
1. 抽象类核心概念
abstract class Class1{ // 普通字段 public string name; public int age; // 普通方法 public void Move() { Console.WriteLine(\"移动\"); } // 抽象方法(无方法体) public abstract void Ai();}
2. 抽象方法实现要求
class Boss : Class1{ // 必须实现抽象方法 public override void Ai() { Console.WriteLine(\"Boss大招\"); }}class Class2 : Class1{ public override void Ai() { Console.WriteLine(\"小兵普攻\"); }}
3. 使用场景与限制
// 抽象类不能被实例化// Class1 c1 = new Class1(); // 编译错误// 通过子类使用Boss b1 = new Boss();b1.name = \"赛伊德\";b1.Ai(); // 输出:Boss大招Class2 c2 = new Class2();c2.Ai(); // 输出:小兵普攻
4. 核心价值
- 模板设计:定义通用结构,强制子类实现特定方法
- 多态支持:通过基类引用调用不同子类实现
- 代码复用:在抽象类中实现通用功能
二、密封类与密封方法:限制继承的利器
1. 密封类定义与使用
sealed class Class1 // 使用sealed关键字{ public int age; public string name; public void Show() { Console.WriteLine($\"{name}, {age}岁\"); }}// 尝试继承会编译错误// class Class2 : Class1 { }
2. 密封方法实现
class Base{ public virtual void Move() { Console.WriteLine(\"基础移动\"); }}class Class2 : Base{ // 密封重写的方法 public sealed override void Move() { Console.WriteLine(\"Class2专属移动\"); }}class Class3 : Class2{ // 无法重写密封方法 // public override void Move() { } }
3. 适用场景
- 商业保护:防止核心类被修改
- 框架设计:固定关键实现
- 性能优化:避免虚方法调用开销
三、子类构造:继承中的初始化顺序
1. 基础构造顺序
class Base{ public Base() { Console.WriteLine(\"父类无参构造\"); }}class Class1 : Base{ public Class1() : base() { Console.WriteLine(\"子类无参构造\"); }}/* 输出:父类无参构造子类无参构造*/
2. 带参构造传递
class Base{ public int Age { get; set; } public string Name { get; set; } public Base(int age, string name) { Age = age; Name = name; Console.WriteLine($\"父类构造设置:{Name}, {Age}岁\"); }}class Class1 : Base{ public int id; public Class1(int id, int age, string name) : base(age, name) { this.id = id; Console.WriteLine($\"子类构造设置ID:{id}\"); }}// 使用示例Class1 c2 = new Class1(20000, 18, \"李四\");/* 输出:父类构造设置:李四, 18岁子类构造设置ID:20000*/
3. 构造关键点
- 执行顺序:父类构造 → 子类构造
- 隐式调用:即使不写
: base()
也会调用父类无参构造 - 参数传递:通过
base(参数)
调用父类特定构造 - 初始化保障:父类字段先于子类初始化
四、综合应用:游戏角色系统设计
完整类体系
// 抽象基类abstract class GameCharacter{ public string Name { get; set; } public int Level { get; set; } public abstract void Attack(); public void DisplayInfo() { Console.WriteLine($\"{Name} (Lv.{Level})\"); }}// 具体角色类sealed class Warrior : GameCharacter{ public Warrior(string name) { Name = name; Level = 1; } public override void Attack() { Console.WriteLine($\"{Name}使用剑攻击!\"); }}class Mage : GameCharacter{ public Mage(string name, int level) : base() { Name = name; Level = level; } public override void Attack() { Console.WriteLine($\"{Name}施展火球术!\"); }}// 使用示例Warrior warrior = new Warrior(\"亚瑟\");warrior.Attack(); // 亚瑟使用剑攻击!Mage mage = new Mage(\"甘道夫\", 10);mage.Attack(); // 甘道夫施展火球术!
学习总结与收获
核心概念对比表
abstract
sealed
base()
关键编程原则
-
抽象类使用:
- 包含通用实现
- 定义必须实现的抽象方法
- 适用于多态场景
-
密封类应用:
- 保护核心实现
- 防止意外继承
- 优化性能(JIT内联)
-
构造最佳实践:
- 显式调用父类构造
- 保持构造逻辑简洁
- 避免在构造中调用虚方法
设计思维提升
-
层次化设计:
-
封装策略:
- 可变逻辑→抽象方法
- 固定实现→密封方法
- 通用功能→基类实现
-
初始化安全:
- 父类先初始化
- 使用构造参数传递必要值
- 避免构造循环依赖
编程箴言
\"优秀的类设计如同精密的齿轮组,每个类都在系统中扮演不可替代的角色\"
学习建议:
- 尝试设计3层类继承体系
- 为关键类添加密封保护
- 练习使用带参基类构造
- 在游戏中应用角色系统设计