跳至内容
张叶安的小站
用户工具
登录
站点工具
搜索
工具
显示页面
过去修订
反向链接
最近更改
媒体管理器
网站地图
登录
>
最近更改
媒体管理器
网站地图
您的足迹:
csharp:第六章继承与多态
本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。
====== 第六章 继承与多态 ====== ===== 6.1 继承基础 ===== === 什么是继承 === 继承是面向对象编程的核心特性之一,允许一个类(子类/派生类)继承另一个类(父类/基类)的成员。 <code csharp> // 基类 public class Animal { public string Name { get; set; } public int Age { get; set; } public void Eat() { Console.WriteLine($"{Name} 正在吃东西"); } public void Sleep() { Console.WriteLine($"{Name} 正在睡觉"); } public virtual void MakeSound() { Console.WriteLine("动物发出声音"); } } // 派生类 public class Dog : Animal { public string Breed { get; set; } public void Fetch() { Console.WriteLine($"{Name} 正在捡球"); } // 重写基类方法 public override void MakeSound() { Console.WriteLine($"{Name} 说: 汪汪!"); } } // 使用 Dog dog = new Dog { Name = "小黑", Age = 3, Breed = "金毛" }; dog.Eat(); // 继承自Animal dog.Fetch(); // Dog自己的方法 dog.MakeSound(); // 调用重写的方法 </code> === 构造函数继承 === <code csharp> public class Person { public string Name { get; set; } public int Age { get; set; } public Person(string name, int age) { Name = name; Age = age; } } public class Employee : Person { public string EmployeeId { get; set; } public decimal Salary { get; set; } // 调用基类构造函数 public Employee(string name, int age, string employeeId, decimal salary) : base(name, age) { EmployeeId = employeeId; Salary = salary; } } // 使用 Employee emp = new Employee("张三", 30, "E001", 5000); </code> ===== 6.2 方法重写(Override) ===== === virtual和override === <code csharp> public class Shape { public string Name { get; set; } // 虚方法:允许子类重写 public virtual double CalculateArea() { return 0; } public virtual void Draw() { Console.WriteLine($"绘制{Name}"); } } public class Circle : Shape { public double Radius { get; set; } public Circle(double radius) { Name = "圆形"; Radius = radius; } // 重写基类方法 public override double CalculateArea() { return Math.PI * Radius * Radius; } public override void Draw() { base.Draw(); // 调用基类实现 Console.WriteLine($"半径: {Radius}"); } } public class Rectangle : Shape { public double Width { get; set; } public double Height { get; set; } public Rectangle(double width, double height) { Name = "矩形"; Width = width; Height = height; } public override double CalculateArea() { return Width * Height; } } </code> === sealed关键字 === <code csharp> public class BaseClass { public virtual void Method() { } } public class DerivedClass : BaseClass { // 阻止进一步重写 public sealed override void Method() { } } // 无法重写sealed方法 // public class FurtherDerived : DerivedClass // { // public override void Method() { } // 编译错误 // } </code> ===== 6.3 抽象类 ===== === 抽象类和抽象方法 === <code csharp> // 抽象类:不能被实例化 public abstract class Vehicle { public string Brand { get; set; } public string Model { get; set; } // 普通方法 public void Start() { Console.WriteLine($"{Brand} {Model} 启动"); } // 抽象方法:必须在子类中实现 public abstract void Drive(); // 抽象属性 public abstract int MaxSpeed { get; } } public class Car : Vehicle { public int TrunkCapacity { get; set; } // 实现抽象方法 public override void Drive() { Console.WriteLine("汽车在公路上行驶"); } public override int MaxSpeed => 200; } public class Motorcycle : Vehicle { public bool HasSidecar { get; set; } public override void Drive() { Console.WriteLine("摩托车灵活穿梭"); } public override int MaxSpeed => 150; } // 使用 Vehicle myCar = new Car { Brand = "Toyota", Model = "Corolla" }; Vehicle myBike = new Motorcycle { Brand = "Honda", Model = "CBR" }; myCar.Drive(); // 输出: 汽车在公路上行驶 myBike.Drive(); // 输出: 摩托车灵活穿梭 </code> ===== 6.4 接口 ===== === 接口定义 === 接口定义一组行为规范,类可以实现多个接口。 <code csharp> // 定义接口 public interface IFlyable { void Fly(); int MaxAltitude { get; } } public interface ISwimmable { void Swim(); int MaxDepth { get; } } public interface IHuntable { void Hunt(); } </code> === 实现接口 === <code csharp> // 实现多个接口 public class Duck : Animal, IFlyable, ISwimmable { public int MaxAltitude => 1000; public int MaxDepth => 5; public void Fly() { Console.WriteLine($"{Name} 在飞翔"); } public void Swim() { Console.WriteLine($"{Name} 在游泳"); } public override void MakeSound() { Console.WriteLine($"{Name} 说: 嘎嘎!"); } } // 使用 Duck duck = new Duck { Name = "唐老鸭" }; duck.Fly(); duck.Swim(); duck.MakeSound(); </code> === 显式接口实现 === <code csharp> public interface IEnglish { void Speak(); } public interface IChinese { void Speak(); } public class BilingualPerson : IEnglish, IChinese { // 显式实现接口 void IEnglish.Speak() { Console.WriteLine("Hello!"); } void IChinese.Speak() { Console.WriteLine("你好!"); } // 默认实现 public void Speak() { Console.WriteLine("Speaking..."); } } // 使用 var person = new BilingualPerson(); person.Speak(); // 调用默认实现 IEnglish english = person; english.Speak(); // 调用英语实现 IChinese chinese = person; chinese.Speak(); // 调用中文实现 </code> ===== 6.5 多态 ===== === 编译时多态(重载) === <code csharp> public class Calculator { // 方法重载 public int Add(int a, int b) => a + b; public double Add(double a, double b) => a + b; public int Add(int a, int b, int c) => a + b + c; public string Add(string a, string b) => a + b; } </code> === 运行时多态(重写) === <code csharp> public class PolymorphismDemo { public static void Main() { // 使用基类引用指向派生类对象 Shape shape1 = new Circle(5); Shape shape2 = new Rectangle(4, 6); // 运行时确定调用哪个方法 Console.WriteLine($"形状1面积: {shape1.CalculateArea():F2}"); Console.WriteLine($"形状2面积: {shape2.CalculateArea():F2}"); // 数组多态 Shape[] shapes = new Shape[] { new Circle(3), new Rectangle(4, 5), new Circle(2) }; double totalArea = 0; foreach (Shape shape in shapes) { totalArea += shape.CalculateArea(); shape.Draw(); Console.WriteLine(); } Console.WriteLine($"总面积: {totalArea:F2}"); } } </code> ===== 6.6 类型转换和判断 ===== === is运算符 === <code csharp> Animal animal = new Dog { Name = "小黑" }; // 类型检查 if (animal is Dog) { Dog dog = (Dog)animal; dog.Fetch(); } // 模式匹配(C# 7+) if (animal is Dog d) { d.Fetch(); } // null检查 if (animal is not null) { Console.WriteLine("animal不为null"); } </code> === as运算符 === <code csharp> Animal animal = new Dog { Name = "小黑" }; // 安全类型转换 Dog dog = animal as Dog; if (dog != null) { dog.Fetch(); } // 转换失败返回null Cat cat = animal as Cat; // cat为null </code> === 强制类型转换 === <code csharp> Animal animal = new Dog { Name = "小黑" }; // 强制转换 Dog dog = (Dog)animal; // 成功 // 转换失败抛出异常 // Cat cat = (Cat)animal; // InvalidCastException </code> ===== 6.7 抽象类 vs 接口 ===== | 特性 | 抽象类 | 接口 | |------|--------|------| | 实例化 | 不能 | 不能 | | 实现 | 单继承 | 多实现 | | 成员 | 可以有实现 | C# 8+可以有默认实现 | | 字段 | 可以有 | 不能有实例字段 | | 构造函数 | 可以有 | 不能有 | | 访问修饰符 | 可以指定 | 默认public | | 使用场景 | "is-a"关系 | "can-do"关系 | <code csharp> // 抽象类示例 - "is-a"关系 public abstract class Bird : Animal { public void LayEgg() { Console.WriteLine("下蛋"); } } // 接口示例 - "can-do"关系 public interface ILogger { void Log(string message); } public class FileLogger : ILogger { public void Log(string message) { File.AppendAllText("log.txt", message + Environment.NewLine); } } </code> ===== 6.8 实战:图形系统 ===== <code csharp> // 可绘制接口 public interface IDrawable { void Draw(); ConsoleColor Color { get; set; } } // 抽象基类 public abstract class Shape : IDrawable { public string Name { get; set; } public ConsoleColor Color { get; set; } = ConsoleColor.White; // 抽象方法 public abstract double CalculateArea(); public abstract double CalculatePerimeter(); // 虚方法 public virtual void Draw() { Console.ForegroundColor = Color; Console.WriteLine($"绘制{Name}"); Console.WriteLine($" 面积: {CalculateArea():F2}"); Console.WriteLine($" 周长: {CalculatePerimeter():F2}"); Console.ResetColor(); } // 具体方法 public void PrintInfo() { Console.WriteLine($"形状: {Name}"); Console.WriteLine($"颜色: {Color}"); } } // 圆形 public class Circle : Shape { public double Radius { get; set; } public Circle(double radius) { Name = "圆形"; Radius = radius; } public override double CalculateArea() => Math.PI * Radius * Radius; public override double CalculatePerimeter() => 2 * Math.PI * Radius; public override void Draw() { base.Draw(); Console.WriteLine($" 半径: {Radius}"); } } // 矩形 public class Rectangle : Shape { public double Width { get; set; } public double Height { get; set; } public Rectangle(double width, double height) { Name = "矩形"; Width = width; Height = height; } public override double CalculateArea() => Width * Height; public override double CalculatePerimeter() => 2 * (Width + Height); public bool IsSquare => Width == Height; public override void Draw() { base.Draw(); Console.WriteLine($" 宽: {Width}, 高: {Height}"); if (IsSquare) { Console.WriteLine(" 这是一个正方形!"); } } } // 三角形 public class Triangle : Shape { public double SideA { get; set; } public double SideB { get; set; } public double SideC { get; set; } public Triangle(double a, double b, double c) { Name = "三角形"; SideA = a; SideB = b; SideC = c; } public override double CalculateArea() { // 海伦公式 double s = CalculatePerimeter() / 2; return Math.Sqrt(s * (s - SideA) * (s - SideB) * (s - SideC)); } public override double CalculatePerimeter() => SideA + SideB + SideC; } // 图形管理器 public class ShapeManager { private List<Shape> shapes = new List<Shape>(); public void AddShape(Shape shape) { shapes.Add(shape); } public void DrawAll() { Console.WriteLine("===== 绘制所有图形 ====="); foreach (var shape in shapes) { shape.Draw(); Console.WriteLine(); } } public double GetTotalArea() { return shapes.Sum(s => s.CalculateArea()); } public Shape FindLargest() { return shapes.OrderByDescending(s => s.CalculateArea()).FirstOrDefault(); } public IEnumerable<T> GetShapesOfType<T>() where T : Shape { return shapes.OfType<T>(); } } // 使用示例 public class ShapeDemo { public static void Main() { var manager = new ShapeManager(); manager.AddShape(new Circle(5) { Color = ConsoleColor.Red }); manager.AddShape(new Rectangle(4, 6) { Color = ConsoleColor.Green }); manager.AddShape(new Rectangle(5, 5) { Color = ConsoleColor.Blue }); manager.AddShape(new Triangle(3, 4, 5) { Color = ConsoleColor.Yellow }); manager.DrawAll(); Console.WriteLine($"总面积: {manager.GetTotalArea():F2}"); var largest = manager.FindLargest(); Console.WriteLine($"最大图形: {largest.Name}"); Console.WriteLine("\n所有矩形:"); foreach (var rect in manager.GetShapesOfType<Rectangle>()) { Console.WriteLine($" - {rect.Width}x{rect.Height}"); } } } </code> ===== 练习题 ===== === 基础练习 === 1. **动物类层次**:创建动物类层次结构: - 基类Animal(Name, Eat(), Sleep()) - 派生类Mammal(有毛发)、Bird(有羽毛)、Fish(有鳞片) - 每个派生类重写MakeSound() - 创建至少两个具体动物类(如Dog、Eagle、Shark) 2. **员工管理系统扩展**:在第五章员工类基础上: - 创建Employee抽象基类 - 实现SalariedEmployee、HourlyEmployee、CommissionEmployee - 每个类实现抽象的CalculatePay()方法 - 创建Employee数组,多态调用CalculatePay() 3. **接口实现**:实现以下接口和类: - IPayable接口(有CalculatePayment()方法) - Invoice类实现IPayable - Employee类也实现IPayable - 创建IPayable数组,统一处理不同类型的应付款项 === 进阶练习 === 4. **游戏角色系统**:设计RPG游戏角色系统: - 抽象基类Character(Name, Health, Attack(), Defend()) - 派生类:Warrior、Mage、Archer - 接口:ICanCastSpell、ICanStealth - 实现不同角色的特殊能力 - 创建战斗系统,角色可以互相攻击 5. **插件系统**:实现一个简单的插件架构: - IPlugin接口(Name, Version, Initialize(), Execute()) - 多个具体插件实现 - 插件管理器动态加载和执行插件 - 支持插件配置 6. **绘图应用**:扩展本章的图形系统: - 添加更多形状(椭圆、多边形) - 实现图层概念(Layer类包含多个Shape) - 实现序列化和反序列化 - 添加撤销/重做功能 === 挑战练习 === 7. **动物园管理系统**:设计完整的动物园管理程序: - Animal抽象基类 - 多种具体动物类 - 饲养员类(可以喂养特定类型的动物) - 笼子/栖息地类 - 实现动物的饮食、健康、繁殖系统 8. **排序策略模式**:实现多种排序算法: - ISortStrategy接口 - BubbleSort、QuickSort、MergeSort等实现 - 允许运行时切换排序策略 - 性能比较 ===== 本章小结 ===== 本章学习了C#的继承与多态: - 继承的语法和构造函数链 - virtual和override实现方法重写 - 抽象类和抽象方法 - 接口的定义和实现 - 编译时多态(重载)和运行时多态(重写) - 类型转换和判断 - 抽象类与接口的区别 这些是面向对象编程的核心概念,理解它们对设计良好的软件架构至关重要。
csharp/第六章继承与多态.txt
· 最后更改:
2026/02/03 19:45
由
127.0.0.1
页面工具
显示页面
过去修订
反向链接
回到顶部