C# 多态
本章将详细介绍面向对象编程的第三个核心特性——多态,包括虚方法、抽象方法、接口多态等概念,帮助你编写更灵活和可扩展的代码。
多态的基本概念
什么是多态
csharp
// 多态(Polymorphism):同一个接口可以有多种不同的实现
// "一个接口,多种实现"
// 基类定义公共接口
public abstract class Shape
{
protected string name;
public Shape(string name)
{
this.name = name;
}
public string Name => name;
// 抽象方法 - 强制派生类实现
public abstract double CalculateArea();
public abstract double CalculatePerimeter();
// 虚方法 - 可以被重写
public virtual void Display()
{
Console.WriteLine($"形状: {name}");
Console.WriteLine($"面积: {CalculateArea():F2}");
Console.WriteLine($"周长: {CalculatePerimeter():F2}");
}
}
// 不同的实现
public class Circle : Shape
{
private double radius;
public Circle(double radius) : base("圆形")
{
this.radius = radius;
}
public double Radius => radius;
public override double CalculateArea()
{
return Math.PI * radius * radius;
}
public override double CalculatePerimeter()
{
return 2 * Math.PI * radius;
}
public override void Display()
{
base.Display();
Console.WriteLine($"半径: {radius}");
}
}
public class Rectangle : Shape
{
private double width, height;
public Rectangle(double width, double height) : base("矩形")
{
this.width = width;
this.height = height;
}
public double Width => width;
public double Height => height;
public override double CalculateArea()
{
return width * height;
}
public override double CalculatePerimeter()
{
return 2 * (width + height);
}
public override void Display()
{
base.Display();
Console.WriteLine($"宽度: {width}, 高度: {height}");
}
}
public class Triangle : Shape
{
private double sideA, sideB, sideC;
public Triangle(double sideA, double sideB, double sideC) : base("三角形")
{
this.sideA = sideA;
this.sideB = sideB;
this.sideC = sideC;
}
public override double CalculateArea()
{
// 使用海伦公式计算面积
double s = (sideA + sideB + sideC) / 2;
return Math.Sqrt(s * (s - sideA) * (s - sideB) * (s - sideC));
}
public override double CalculatePerimeter()
{
return sideA + sideB + sideC;
}
public override void Display()
{
base.Display();
Console.WriteLine($"边长: {sideA}, {sideB}, {sideC}");
}
}
static void BasicPolymorphismDemo()
{
Console.WriteLine("=== 基本多态演示 ===");
// 多态性:基类引用指向不同的派生类对象
Shape[] shapes = {
new Circle(5.0),
new Rectangle(4.0, 6.0),
new Triangle(3.0, 4.0, 5.0)
};
// 统一的接口,不同的实现
foreach (Shape shape in shapes)
{
shape.Display(); // 调用相应派生类的实现
Console.WriteLine();
}
// 计算总面积
double totalArea = 0;
foreach (Shape shape in shapes)
{
totalArea += shape.CalculateArea();
}
Console.WriteLine($"所有形状的总面积: {totalArea:F2}");
}多态的类型
csharp
// 1. 编译时多态(静态多态)- 方法重载
public class Calculator
{
// 方法重载 - 编译时确定调用哪个方法
public int Add(int a, int b)
{
Console.WriteLine("调用 int Add(int, int)");
return a + b;
}
public double Add(double a, double b)
{
Console.WriteLine("调用 double Add(double, double)");
return a + b;
}
public string Add(string a, string b)
{
Console.WriteLine("调用 string Add(string, string)");
return a + b;
}
public int Add(int a, int b, int c)
{
Console.WriteLine("调用 int Add(int, int, int)");
return a + b + c;
}
}
// 2. 运行时多态(动态多态)- 虚方法重写
public abstract class Animal
{
protected string name;
public Animal(string name)
{
this.name = name;
}
public string Name => name;
// 虚方法 - 运行时确定调用哪个实现
public virtual void MakeSound()
{
Console.WriteLine($"{name} 发出声音");
}
public virtual void Move()
{
Console.WriteLine($"{name} 在移动");
}
// 抽象方法 - 必须重写
public abstract void Eat();
}
public class Dog : Animal
{
public Dog(string name) : base(name) { }
public override void MakeSound()
{
Console.WriteLine($"{name} 汪汪叫");
}
public override void Move()
{
Console.WriteLine($"{name} 在奔跑");
}
public override void Eat()
{
Console.WriteLine($"{name} 在吃狗粮");
}
// 新增方法
public void Fetch()
{
Console.WriteLine($"{name} 在捡球");
}
}
public class Cat : Animal
{
public Cat(string name) : base(name) { }
public override void MakeSound()
{
Console.WriteLine($"{name} 喵喵叫");
}
public override void Move()
{
Console.WriteLine($"{name} 在悄悄走动");
}
public override void Eat()
{
Console.WriteLine($"{name} 在吃猫粮");
}
public void Climb()
{
Console.WriteLine($"{name} 在爬树");
}
}
public class Bird : Animal
{
public Bird(string name) : base(name) { }
public override void MakeSound()
{
Console.WriteLine($"{name} 在唱歌");
}
public override void Move()
{
Console.WriteLine($"{name} 在飞翔");
}
public override void Eat()
{
Console.WriteLine($"{name} 在吃虫子");
}
public void Fly()
{
Console.WriteLine($"{name} 在高空飞行");
}
}
static void PolymorphismTypesDemo()
{
Console.WriteLine("=== 多态类型演示 ===");
// 编译时多态
Console.WriteLine("1. 编译时多态(方法重载):");
Calculator calc = new Calculator();
calc.Add(1, 2);
calc.Add(1.5, 2.5);
calc.Add("Hello", "World");
calc.Add(1, 2, 3);
// 运行时多态
Console.WriteLine("\n2. 运行时多态(虚方法重写):");
Animal[] animals = {
new Dog("旺财"),
new Cat("咪咪"),
new Bird("小鸟")
};
foreach (Animal animal in animals)
{
Console.WriteLine($"\n--- {animal.Name} ---");
animal.MakeSound(); // 多态调用
animal.Move(); // 多态调用
animal.Eat(); // 多态调用
}
}虚方法和抽象方法
虚方法的深入应用
csharp
public class Vehicle
{
protected string brand;
protected int year;
protected decimal price;
public Vehicle(string brand, int year, decimal price)
{
this.brand = brand;
this.year = year;
this.price = price;
}
public string Brand => brand;
public int Year => year;
public decimal Price => price;
// 虚方法 - 提供默认实现,可以被重写
public virtual void Start()
{
Console.WriteLine($"{brand} 正在启动...");
}
public virtual void Stop()
{
Console.WriteLine($"{brand} 已停止");
}
public virtual decimal CalculateInsurance()
{
return price * 0.05m; // 默认保险费率 5%
}
public virtual string GetVehicleInfo()
{
return $"{brand} {year}年款,价格: {price:C}";
}
// 模板方法模式 - 定义算法骨架
public void PerformMaintenance()
{
Console.WriteLine($"开始维护 {brand}:");
CheckEngine(); // 虚方法
CheckTires(); // 虚方法
CheckFluids(); // 虚方法
PerformSpecificMaintenance(); // 抽象方法
Console.WriteLine("维护完成\n");
}
protected virtual void CheckEngine()
{
Console.WriteLine("- 检查发动机");
}
protected virtual void CheckTires()
{
Console.WriteLine("- 检查轮胎");
}
protected virtual void CheckFluids()
{
Console.WriteLine("- 检查液体");
}
protected virtual void PerformSpecificMaintenance()
{
Console.WriteLine("- 执行通用维护");
}
}
public class Car : Vehicle
{
private int doors;
private string fuelType;
public Car(string brand, int year, decimal price, int doors, string fuelType)
: base(brand, year, price)
{
this.doors = doors;
this.fuelType = fuelType;
}
public int Doors => doors;
public string FuelType => fuelType;
public override void Start()
{
Console.WriteLine($"{brand} 汽车启动,{fuelType}发动机运转");
}
public override decimal CalculateInsurance()
{
decimal baseInsurance = base.CalculateInsurance();
// 汽车保险费率根据门数调整
decimal doorFactor = doors == 2 ? 1.2m : 1.0m;
return baseInsurance * doorFactor;
}
public override string GetVehicleInfo()
{
return base.GetVehicleInfo() + $", {doors}门 {fuelType}汽车";
}
protected override void PerformSpecificMaintenance()
{
Console.WriteLine("- 检查空调系统");
Console.WriteLine("- 检查音响系统");
Console.WriteLine("- 清洁内饰");
}
}
public class Motorcycle : Vehicle
{
private int engineSize;
public Motorcycle(string brand, int year, decimal price, int engineSize)
: base(brand, year, price)
{
this.engineSize = engineSize;
}
public int EngineSize => engineSize;
public override void Start()
{
Console.WriteLine($"{brand} 摩托车启动,{engineSize}cc发动机轰鸣");
}
public override decimal CalculateInsurance()
{
decimal baseInsurance = base.CalculateInsurance();
// 摩托车保险费率更高
return baseInsurance * 1.5m;
}
public override string GetVehicleInfo()
{
return base.GetVehicleInfo() + $", {engineSize}cc摩托车";
}
protected override void CheckTires()
{
Console.WriteLine("- 检查摩托车轮胎气压和磨损");
}
protected override void PerformSpecificMaintenance()
{
Console.WriteLine("- 检查链条润滑");
Console.WriteLine("- 检查刹车片");
Console.WriteLine("- 调整后视镜");
}
}
public class Truck : Vehicle
{
private double loadCapacity;
public Truck(string brand, int year, decimal price, double loadCapacity)
: base(brand, year, price)
{
this.loadCapacity = loadCapacity;
}
public double LoadCapacity => loadCapacity;
public override void Start()
{
Console.WriteLine($"{brand} 卡车启动,载重量 {loadCapacity}吨");
}
public override decimal CalculateInsurance()
{
decimal baseInsurance = base.CalculateInsurance();
// 卡车保险费率根据载重量调整
decimal loadFactor = (decimal)(1.0 + loadCapacity * 0.1);
return baseInsurance * loadFactor;
}
public override string GetVehicleInfo()
{
return base.GetVehicleInfo() + $", 载重 {loadCapacity}吨卡车";
}
protected override void CheckEngine()
{
Console.WriteLine("- 检查大型柴油发动机");
}
protected override void PerformSpecificMaintenance()
{
Console.WriteLine("- 检查货厢");
Console.WriteLine("- 检查液压系统");
Console.WriteLine("- 润滑传动系统");
}
}
static void VirtualMethodDemo()
{
Console.WriteLine("=== 虚方法演示 ===");
Vehicle[] vehicles = {
new Car("丰田", 2023, 200000m, 4, "汽油"),
new Motorcycle("哈雷", 2022, 150000m, 1200),
new Truck("沃尔沃", 2021, 500000m, 10.0)
};
foreach (Vehicle vehicle in vehicles)
{
Console.WriteLine(vehicle.GetVehicleInfo());
vehicle.Start();
Console.WriteLine($"保险费: {vehicle.CalculateInsurance():C}");
vehicle.PerformMaintenance();
}
}抽象方法的应用
csharp
// 抽象基类定义公共接口
public abstract class DatabaseConnection
{
protected string connectionString;
protected bool isConnected;
public DatabaseConnection(string connectionString)
{
this.connectionString = connectionString;
this.isConnected = false;
}
public string ConnectionString => connectionString;
public bool IsConnected => isConnected;
// 抽象方法 - 强制派生类实现
public abstract void Connect();
public abstract void Disconnect();
public abstract void ExecuteQuery(string query);
public abstract void BeginTransaction();
public abstract void CommitTransaction();
public abstract void RollbackTransaction();
// 虚方法 - 提供默认实现,可以重写
public virtual void TestConnection()
{
Console.WriteLine("测试数据库连接...");
Connect();
if (isConnected)
{
Console.WriteLine("连接测试成功");
Disconnect();
}
else
{
Console.WriteLine("连接测试失败");
}
}
// 模板方法 - 定义操作流程
public void ExecuteWithTransaction(string[] queries)
{
try
{
Connect();
BeginTransaction();
foreach (string query in queries)
{
ExecuteQuery(query);
}
CommitTransaction();
Console.WriteLine("事务执行成功");
}
catch (Exception ex)
{
Console.WriteLine($"事务执行失败: {ex.Message}");
RollbackTransaction();
}
finally
{
Disconnect();
}
}
}
public class SqlServerConnection : DatabaseConnection
{
public SqlServerConnection(string connectionString) : base(connectionString) { }
public override void Connect()
{
Console.WriteLine($"连接到 SQL Server: {connectionString}");
isConnected = true;
}
public override void Disconnect()
{
Console.WriteLine("断开 SQL Server 连接");
isConnected = false;
}
public override void ExecuteQuery(string query)
{
if (!isConnected)
throw new InvalidOperationException("未连接到数据库");
Console.WriteLine($"SQL Server 执行查询: {query}");
}
public override void BeginTransaction()
{
Console.WriteLine("SQL Server 开始事务");
}
public override void CommitTransaction()
{
Console.WriteLine("SQL Server 提交事务");
}
public override void RollbackTransaction()
{
Console.WriteLine("SQL Server 回滚事务");
}
public override void TestConnection()
{
Console.WriteLine("SQL Server 专用连接测试");
base.TestConnection();
}
}
public class MySqlConnection : DatabaseConnection
{
public MySqlConnection(string connectionString) : base(connectionString) { }
public override void Connect()
{
Console.WriteLine($"连接到 MySQL: {connectionString}");
isConnected = true;
}
public override void Disconnect()
{
Console.WriteLine("断开 MySQL 连接");
isConnected = false;
}
public override void ExecuteQuery(string query)
{
if (!isConnected)
throw new InvalidOperationException("未连接到数据库");
Console.WriteLine($"MySQL 执行查询: {query}");
}
public override void BeginTransaction()
{
Console.WriteLine("MySQL 开始事务");
}
public override void CommitTransaction()
{
Console.WriteLine("MySQL 提交事务");
}
public override void RollbackTransaction()
{
Console.WriteLine("MySQL 回滚事务");
}
}
public class OracleConnection : DatabaseConnection
{
public OracleConnection(string connectionString) : base(connectionString) { }
public override void Connect()
{
Console.WriteLine($"连接到 Oracle: {connectionString}");
isConnected = true;
}
public override void Disconnect()
{
Console.WriteLine("断开 Oracle 连接");
isConnected = false;
}
public override void ExecuteQuery(string query)
{
if (!isConnected)
throw new InvalidOperationException("未连接到数据库");
Console.WriteLine($"Oracle 执行查询: {query}");
}
public override void BeginTransaction()
{
Console.WriteLine("Oracle 开始事务");
}
public override void CommitTransaction()
{
Console.WriteLine("Oracle 提交事务");
}
public override void RollbackTransaction()
{
Console.WriteLine("Oracle 回滚事务");
}
}
// 数据库管理器 - 使用多态
public class DatabaseManager
{
private List<DatabaseConnection> connections;
public DatabaseManager()
{
connections = new List<DatabaseConnection>();
}
public void AddConnection(DatabaseConnection connection)
{
connections.Add(connection);
}
public void TestAllConnections()
{
Console.WriteLine("测试所有数据库连接:");
foreach (var connection in connections)
{
connection.TestConnection();
Console.WriteLine();
}
}
public void ExecuteQueryOnAll(string query)
{
Console.WriteLine($"在所有数据库上执行查询: {query}");
foreach (var connection in connections)
{
try
{
connection.Connect();
connection.ExecuteQuery(query);
connection.Disconnect();
}
catch (Exception ex)
{
Console.WriteLine($"执行失败: {ex.Message}");
}
Console.WriteLine();
}
}
}
static void AbstractMethodDemo()
{
Console.WriteLine("=== 抽象方法演示 ===");
DatabaseManager manager = new DatabaseManager();
// 添加不同类型的数据库连接
manager.AddConnection(new SqlServerConnection("Server=localhost;Database=TestDB"));
manager.AddConnection(new MySqlConnection("Server=localhost;Database=testdb;Uid=root"));
manager.AddConnection(new OracleConnection("Data Source=localhost:1521/XE"));
// 多态调用
manager.TestAllConnections();
manager.ExecuteQueryOnAll("SELECT * FROM Users");
// 事务演示
Console.WriteLine("=== 事务演示 ===");
var sqlConnection = new SqlServerConnection("Server=localhost;Database=TestDB");
string[] queries = {
"INSERT INTO Users (Name) VALUES ('Alice')",
"INSERT INTO Users (Name) VALUES ('Bob')",
"UPDATE Users SET Active = 1"
};
sqlConnection.ExecuteWithTransaction(queries);
}接口多态
接口的定义和实现
csharp
// 接口定义契约
public interface IDrawable
{
void Draw();
void Move(int x, int y);
bool IsVisible { get; set; }
}
public interface IResizable
{
void Resize(double factor);
double GetArea();
}
public interface IColorable
{
ConsoleColor Color { get; set; }
void ChangeColor(ConsoleColor newColor);
}
// 实现多个接口
public class DrawableRectangle : IDrawable, IResizable, IColorable
{
private int x, y;
private double width, height;
private ConsoleColor color;
private bool isVisible;
public DrawableRectangle(int x, int y, double width, double height, ConsoleColor color = ConsoleColor.White)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.isVisible = true;
}
// IDrawable 实现
public void Draw()
{
if (isVisible)
{
Console.ForegroundColor = color;
Console.WriteLine($"绘制矩形在 ({x}, {y}),大小: {width} x {height}");
Console.ResetColor();
}
}
public void Move(int newX, int newY)
{
x = newX;
y = newY;
Console.WriteLine($"矩形移动到 ({x}, {y})");
}
public bool IsVisible
{
get => isVisible;
set
{
isVisible = value;
Console.WriteLine($"矩形可见性: {(isVisible ? "显示" : "隐藏")}");
}
}
// IResizable 实现
public void Resize(double factor)
{
width *= factor;
height *= factor;
Console.WriteLine($"矩形缩放 {factor}倍,新大小: {width:F2} x {height:F2}");
}
public double GetArea()
{
return width * height;
}
// IColorable 实现
public ConsoleColor Color
{
get => color;
set
{
color = value;
Console.WriteLine($"矩形颜色改为: {color}");
}
}
public void ChangeColor(ConsoleColor newColor)
{
Color = newColor;
}
}
public class DrawableCircle : IDrawable, IResizable, IColorable
{
private int x, y;
private double radius;
private ConsoleColor color;
private bool isVisible;
public DrawableCircle(int x, int y, double radius, ConsoleColor color = ConsoleColor.White)
{
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.isVisible = true;
}
public void Draw()
{
if (isVisible)
{
Console.ForegroundColor = color;
Console.WriteLine($"绘制圆形在 ({x}, {y}),半径: {radius}");
Console.ResetColor();
}
}
public void Move(int newX, int newY)
{
x = newX;
y = newY;
Console.WriteLine($"圆形移动到 ({x}, {y})");
}
public bool IsVisible
{
get => isVisible;
set
{
isVisible = value;
Console.WriteLine($"圆形可见性: {(isVisible ? "显示" : "隐藏")}");
}
}
public void Resize(double factor)
{
radius *= factor;
Console.WriteLine($"圆形缩放 {factor}倍,新半径: {radius:F2}");
}
public double GetArea()
{
return Math.PI * radius * radius;
}
public ConsoleColor Color
{
get => color;
set
{
color = value;
Console.WriteLine($"圆形颜色改为: {color}");
}
}
public void ChangeColor(ConsoleColor newColor)
{
Color = newColor;
}
}
// 图形管理器 - 使用接口多态
public class GraphicsManager
{
private List<IDrawable> drawables;
private List<IResizable> resizables;
private List<IColorable> colorables;
public GraphicsManager()
{
drawables = new List<IDrawable>();
resizables = new List<IResizable>();
colorables = new List<IColorable>();
}
public void AddShape(object shape)
{
if (shape is IDrawable drawable)
drawables.Add(drawable);
if (shape is IResizable resizable)
resizables.Add(resizable);
if (shape is IColorable colorable)
colorables.Add(colorable);
}
public void DrawAll()
{
Console.WriteLine("绘制所有图形:");
foreach (var drawable in drawables)
{
drawable.Draw();
}
}
public void MoveAll(int deltaX, int deltaY)
{
Console.WriteLine($"移动所有图形 ({deltaX}, {deltaY}):");
foreach (var drawable in drawables)
{
// 这里需要获取当前位置,简化处理
drawable.Move(deltaX, deltaY);
}
}
public void ResizeAll(double factor)
{
Console.WriteLine($"缩放所有可调整大小的图形 {factor}倍:");
foreach (var resizable in resizables)
{
resizable.Resize(factor);
}
}
public void ChangeAllColors(ConsoleColor newColor)
{
Console.WriteLine($"将所有图形颜色改为 {newColor}:");
foreach (var colorable in colorables)
{
colorable.ChangeColor(newColor);
}
}
public void ShowStatistics()
{
Console.WriteLine("图形统计:");
Console.WriteLine($"可绘制图形: {drawables.Count}");
Console.WriteLine($"可调整大小图形: {resizables.Count}");
Console.WriteLine($"可着色图形: {colorables.Count}");
double totalArea = 0;
foreach (var resizable in resizables)
{
totalArea += resizable.GetArea();
}
Console.WriteLine($"总面积: {totalArea:F2}");
}
}
static void InterfacePolymorphismDemo()
{
Console.WriteLine("=== 接口多态演示 ===");
GraphicsManager manager = new GraphicsManager();
// 添加不同类型的图形
manager.AddShape(new DrawableRectangle(10, 10, 5, 3, ConsoleColor.Red));
manager.AddShape(new DrawableCircle(20, 20, 4, ConsoleColor.Blue));
manager.AddShape(new DrawableRectangle(30, 30, 6, 4, ConsoleColor.Green));
// 使用接口多态
manager.DrawAll();
Console.WriteLine();
manager.ShowStatistics();
Console.WriteLine();
manager.ResizeAll(1.5);
Console.WriteLine();
manager.ChangeAllColors(ConsoleColor.Yellow);
Console.WriteLine();
manager.DrawAll();
}实践示例
示例 1:支付系统
csharp
using System;
using System.Collections.Generic;
// 支付接口
public interface IPaymentProcessor
{
bool ProcessPayment(decimal amount, string currency = "CNY");
bool RefundPayment(string transactionId, decimal amount);
string GetPaymentMethod();
decimal GetTransactionFee(decimal amount);
}
// 抽象支付基类
public abstract class PaymentProcessorBase : IPaymentProcessor
{
protected string merchantId;
protected bool isEnabled;
public PaymentProcessorBase(string merchantId)
{
this.merchantId = merchantId;
this.isEnabled = true;
}
public string MerchantId => merchantId;
public bool IsEnabled => isEnabled;
// 抽象方法 - 子类必须实现
public abstract bool ProcessPayment(decimal amount, string currency = "CNY");
public abstract bool RefundPayment(string transactionId, decimal amount);
public abstract string GetPaymentMethod();
public abstract decimal GetTransactionFee(decimal amount);
// 虚方法 - 可以被重写
public virtual bool ValidateAmount(decimal amount)
{
return amount > 0 && amount <= GetMaxAmount();
}
public virtual decimal GetMaxAmount()
{
return 100000m; // 默认最大金额
}
// 模板方法
public bool ExecutePayment(decimal amount, string currency = "CNY")
{
if (!isEnabled)
{
Console.WriteLine($"{GetPaymentMethod()} 支付已禁用");
return false;
}
if (!ValidateAmount(amount))
{
Console.WriteLine($"金额验证失败: {amount:C}");
return false;
}
decimal fee = GetTransactionFee(amount);
Console.WriteLine($"使用 {GetPaymentMethod()} 支付 {amount:C},手续费: {fee:C}");
return ProcessPayment(amount, currency);
}
}
// 支付宝支付
public class AlipayProcessor : PaymentProcessorBase
{
private string appId;
public AlipayProcessor(string merchantId, string appId) : base(merchantId)
{
this.appId = appId;
}
public override bool ProcessPayment(decimal amount, string currency = "CNY")
{
Console.WriteLine($"支付宝处理支付: {amount:C} {currency}");
// 模拟支付处理
bool success = new Random().Next(1, 11) > 1; // 90% 成功率
Console.WriteLine($"支付宝支付{(success ? "成功" : "失败")}");
return success;
}
public override bool RefundPayment(string transactionId, decimal amount)
{
Console.WriteLine($"支付宝退款: 交易ID {transactionId},金额 {amount:C}");
return true;
}
public override string GetPaymentMethod()
{
return "支付宝";
}
public override decimal GetTransactionFee(decimal amount)
{
return amount * 0.006m; // 0.6% 手续费
}
public override decimal GetMaxAmount()
{
return 200000m; // 支付宝单笔限额更高
}
}
// 微信支付
public class WeChatPayProcessor : PaymentProcessorBase
{
private string appSecret;
public WeChatPayProcessor(string merchantId, string appSecret) : base(merchantId)
{
this.appSecret = appSecret;
}
public override bool ProcessPayment(decimal amount, string currency = "CNY")
{
Console.WriteLine($"微信支付处理支付: {amount:C} {currency}");
bool success = new Random().Next(1, 11) > 2; // 80% 成功率
Console.WriteLine($"微信支付{(success ? "成功" : "失败")}");
return success;
}
public override bool RefundPayment(string transactionId, decimal amount)
{
Console.WriteLine($"微信支付退款: 交易ID {transactionId},金额 {amount:C}");
return true;
}
public override string GetPaymentMethod()
{
return "微信支付";
}
public override decimal GetTransactionFee(decimal amount)
{
return amount * 0.006m; // 0.6% 手续费
}
}
// 银行卡支付
public class BankCardProcessor : PaymentProcessorBase
{
private string bankCode;
public BankCardProcessor(string merchantId, string bankCode) : base(merchantId)
{
this.bankCode = bankCode;
}
public override bool ProcessPayment(decimal amount, string currency = "CNY")
{
Console.WriteLine($"银行卡支付处理: {amount:C} {currency},银行代码: {bankCode}");
bool success = new Random().Next(1, 11) > 3; // 70% 成功率
Console.WriteLine($"银行卡支付{(success ? "成功" : "失败")}");
return success;
}
public override bool RefundPayment(string transactionId, decimal amount)
{
Console.WriteLine($"银行卡退款: 交易ID {transactionId},金额 {amount:C}");
return true;
}
public override string GetPaymentMethod()
{
return $"银行卡({bankCode})";
}
public override decimal GetTransactionFee(decimal amount)
{
return amount * 0.008m; // 0.8% 手续费
}
public override bool ValidateAmount(decimal amount)
{
// 银行卡支付额外验证
return base.ValidateAmount(amount) && amount >= 1m; // 最小1元
}
}
// 支付管理器
public class PaymentManager
{
private List<IPaymentProcessor> processors;
private IPaymentProcessor defaultProcessor;
public PaymentManager()
{
processors = new List<IPaymentProcessor>();
}
public void AddProcessor(IPaymentProcessor processor)
{
processors.Add(processor);
if (defaultProcessor == null)
defaultProcessor = processor;
}
public void SetDefaultProcessor(IPaymentProcessor processor)
{
defaultProcessor = processor;
}
public bool ProcessPayment(decimal amount, string preferredMethod = null)
{
IPaymentProcessor processor = null;
// 选择支付方式
if (!string.IsNullOrEmpty(preferredMethod))
{
processor = processors.Find(p => p.GetPaymentMethod().Contains(preferredMethod));
}
processor ??= defaultProcessor;
if (processor == null)
{
Console.WriteLine("没有可用的支付处理器");
return false;
}
// 使用多态调用
if (processor is PaymentProcessorBase baseProcessor)
{
return baseProcessor.ExecutePayment(amount);
}
else
{
return processor.ProcessPayment(amount);
}
}
public void ShowAvailablePaymentMethods()
{
Console.WriteLine("可用支付方式:");
foreach (var processor in processors)
{
decimal sampleFee = processor.GetTransactionFee(100m);
Console.WriteLine($"- {processor.GetPaymentMethod()}: 手续费率 {sampleFee:P2}");
}
}
public void ProcessMultiplePayments(decimal[] amounts)
{
Console.WriteLine("批量支付处理:");
foreach (decimal amount in amounts)
{
Console.WriteLine($"\n处理支付: {amount:C}");
// 根据金额选择最优支付方式
IPaymentProcessor bestProcessor = GetBestProcessor(amount);
if (bestProcessor is PaymentProcessorBase baseProcessor)
{
baseProcessor.ExecutePayment(amount);
}
}
}
private IPaymentProcessor GetBestProcessor(decimal amount)
{
// 选择手续费最低的支付方式
IPaymentProcessor best = null;
decimal lowestFee = decimal.MaxValue;
foreach (var processor in processors)
{
decimal fee = processor.GetTransactionFee(amount);
if (fee < lowestFee)
{
lowestFee = fee;
best = processor;
}
}
return best ?? defaultProcessor;
}
}
static void PaymentSystemDemo()
{
Console.WriteLine("=== 支付系统演示 ===");
PaymentManager manager = new PaymentManager();
// 添加不同的支付处理器
manager.AddProcessor(new AlipayProcessor("MERCHANT001", "APP001"));
manager.AddProcessor(new WeChatPayProcessor("MERCHANT001", "SECRET001"));
manager.AddProcessor(new BankCardProcessor("MERCHANT001", "ICBC"));
// 显示可用支付方式
manager.ShowAvailablePaymentMethods();
Console.WriteLine("\n=== 单笔支付测试 ===");
manager.ProcessPayment(1000m, "支付宝");
manager.ProcessPayment(500m, "微信");
manager.ProcessPayment(2000m, "银行卡");
Console.WriteLine("\n=== 批量支付测试 ===");
decimal[] amounts = { 100m, 500m, 1500m, 3000m };
manager.ProcessMultiplePayments(amounts);
}示例 2:文档处理系统
csharp
using System;
using System.Collections.Generic;
using System.IO;
// 文档接口
public interface IDocument
{
string FileName { get; }
long FileSize { get; }
DateTime CreatedDate { get; }
void Open();
void Save();
void Close();
string GetContent();
}
public interface IEditableDocument : IDocument
{
void SetContent(string content);
void AppendContent(string content);
bool IsModified { get; }
}
public interface IPrintableDocument : IDocument
{
void Print();
void PrintPreview();
int GetPageCount();
}
public interface IExportableDocument : IDocument
{
void ExportToPdf(string filePath);
void ExportToHtml(string filePath);
}
// 抽象文档基类
public abstract class DocumentBase : IDocument
{
protected string fileName;
protected long fileSize;
protected DateTime createdDate;
protected bool isOpen;
protected string content;
public DocumentBase(string fileName)
{
this.fileName = fileName;
this.fileSize = 0;
this.createdDate = DateTime.Now;
this.isOpen = false;
this.content = "";
}
public string FileName => fileName;
public long FileSize => fileSize;
public DateTime CreatedDate => createdDate;
public bool IsOpen => isOpen;
public virtual void Open()
{
if (!isOpen)
{
Console.WriteLine($"打开文档: {fileName}");
LoadContent();
isOpen = true;
}
}
public virtual void Close()
{
if (isOpen)
{
Console.WriteLine($"关闭文档: {fileName}");
isOpen = false;
}
}
public abstract void Save();
public abstract string GetContent();
protected abstract void LoadContent();
}
// 文本文档
public class TextDocument : DocumentBase, IEditableDocument, IPrintableDocument, IExportableDocument
{
private bool isModified;
public TextDocument(string fileName) : base(fileName)
{
this.isModified = false;
}
public bool IsModified => isModified;
protected override void LoadContent()
{
// 模拟从文件加载内容
content = $"这是文本文档 {fileName} 的内容。\n创建时间: {createdDate}";
fileSize = content.Length;
}
public override void Save()
{
if (isModified)
{
Console.WriteLine($"保存文本文档: {fileName}");
fileSize = content.Length;
isModified = false;
}
else
{
Console.WriteLine($"文档 {fileName} 无需保存");
}
}
public override string GetContent()
{
return content;
}
public void SetContent(string newContent)
{
if (content != newContent)
{
content = newContent;
isModified = true;
Console.WriteLine($"文档 {fileName} 内容已修改");
}
}
public void AppendContent(string additionalContent)
{
content += additionalContent;
isModified = true;
Console.WriteLine($"向文档 {fileName} 追加内容");
}
public void Print()
{
Console.WriteLine($"打印文本文档: {fileName}");
Console.WriteLine("--- 打印内容 ---");
Console.WriteLine(content);
Console.WriteLine("--- 打印结束 ---");
}
public void PrintPreview()
{
Console.WriteLine($"文本文档 {fileName} 打印预览:");
Console.WriteLine($"页数: {GetPageCount()}");
Console.WriteLine($"字符数: {content.Length}");
}
public int GetPageCount()
{
return Math.Max(1, content.Length / 500); // 假设每页500字符
}
public void ExportToPdf(string filePath)
{
Console.WriteLine($"将文本文档 {fileName} 导出为PDF: {filePath}");
}
public void ExportToHtml(string filePath)
{
Console.WriteLine($"将文本文档 {fileName} 导出为HTML: {filePath}");
}
}
// 图片文档
public class ImageDocument : DocumentBase, IPrintableDocument, IExportableDocument
{
private int width, height;
private string format;
public ImageDocument(string fileName, int width, int height, string format) : base(fileName)
{
this.width = width;
this.height = height;
this.format = format;
}
public int Width => width;
public int Height => height;
public string Format => format;
protected override void LoadContent()
{
content = $"图片文档: {fileName} ({width}x{height}, {format})";
fileSize = width * height * 3; // 假设RGB格式
}
public override void Save()
{
Console.WriteLine($"保存图片文档: {fileName}");
}
public override string GetContent()
{
return $"图片信息: {width}x{height} {format}格式";
}
public void Print()
{
Console.WriteLine($"打印图片文档: {fileName}");
Console.WriteLine($"图片尺寸: {width}x{height}");
Console.WriteLine($"格式: {format}");
}
public void PrintPreview()
{
Console.WriteLine($"图片文档 {fileName} 打印预览:");
Console.WriteLine($"尺寸: {width}x{height}");
Console.WriteLine($"格式: {format}");
Console.WriteLine($"文件大小: {fileSize} 字节");
}
public int GetPageCount()
{
return 1; // 图片通常只有一页
}
public void ExportToPdf(string filePath)
{
Console.WriteLine($"将图片文档 {fileName} 导出为PDF: {filePath}");
}
public void ExportToHtml(string filePath)
{
Console.WriteLine($"将图片文档 {fileName} 嵌入HTML: {filePath}");
}
public void Resize(int newWidth, int newHeight)
{
Console.WriteLine($"调整图片 {fileName} 尺寸: {width}x{height} -> {newWidth}x{newHeight}");
width = newWidth;
height = newHeight;
fileSize = width * height * 3;
}
}
// PDF文档
public class PdfDocument : DocumentBase, IPrintableDocument
{
private int pageCount;
public PdfDocument(string fileName, int pageCount) : base(fileName)
{
this.pageCount = pageCount;
}
protected override void LoadContent()
{
content = $"PDF文档: {fileName},共 {pageCount} 页";
fileSize = pageCount * 50000; // 假设每页50KB
}
public override void Save()
{
Console.WriteLine($"保存PDF文档: {fileName}");
}
public override string GetContent()
{
return $"PDF文档,共 {pageCount} 页";
}
public void Print()
{
Console.WriteLine($"打印PDF文档: {fileName}");
Console.WriteLine($"页数: {pageCount}");
}
public void PrintPreview()
{
Console.WriteLine($"PDF文档 {fileName} 打印预览:");
Console.WriteLine($"总页数: {pageCount}");
Console.WriteLine($"文件大小: {fileSize} 字节");
}
public int GetPageCount()
{
return pageCount;
}
public void AddPage()
{
pageCount++;
fileSize += 50000;
Console.WriteLine($"PDF文档 {fileName} 添加页面,当前页数: {pageCount}");
}
}
// 文档管理器
public class DocumentManager
{
private List<IDocument> documents;
public DocumentManager()
{
documents = new List<IDocument>();
}
public void AddDocument(IDocument document)
{
documents.Add(document);
Console.WriteLine($"添加文档: {document.FileName}");
}
public void OpenAllDocuments()
{
Console.WriteLine("打开所有文档:");
foreach (var doc in documents)
{
doc.Open();
}
}
public void SaveAllDocuments()
{
Console.WriteLine("保存所有文档:");
foreach (var doc in documents)
{
doc.Save();
}
}
public void PrintAllDocuments()
{
Console.WriteLine("打印所有可打印文档:");
foreach (var doc in documents)
{
if (doc is IPrintableDocument printable)
{
printable.Print();
Console.WriteLine();
}
}
}
public void EditTextDocuments(string newContent)
{
Console.WriteLine("编辑所有文本文档:");
foreach (var doc in documents)
{
if (doc is IEditableDocument editable)
{
editable.AppendContent($"\n{newContent}");
}
}
}
public void ExportAllToHtml(string directory)
{
Console.WriteLine($"导出所有文档到HTML格式,目录: {directory}");
foreach (var doc in documents)
{
if (doc is IExportableDocument exportable)
{
string htmlPath = Path.Combine(directory, Path.ChangeExtension(doc.FileName, ".html"));
exportable.ExportToHtml(htmlPath);
}
}
}
public void ShowDocumentStatistics()
{
Console.WriteLine("文档统计:");
Console.WriteLine($"总文档数: {documents.Count}");
int editableCount = 0;
int printableCount = 0;
int exportableCount = 0;
long totalSize = 0;
int totalPages = 0;
foreach (var doc in documents)
{
totalSize += doc.FileSize;
if (doc is IEditableDocument) editableCount++;
if (doc is IPrintableDocument printable)
{
printableCount++;
totalPages += printable.GetPageCount();
}
if (doc is IExportableDocument) exportableCount++;
}
Console.WriteLine($"可编辑文档: {editableCount}");
Console.WriteLine($"可打印文档: {printableCount}");
Console.WriteLine($"可导出文档: {exportableCount}");
Console.WriteLine($"总文件大小: {totalSize:N0} 字节");
Console.WriteLine($"总页数: {totalPages}");
}
}
static void DocumentSystemDemo()
{
Console.WriteLine("=== 文档处理系统演示 ===");
DocumentManager manager = new DocumentManager();
// 添加不同类型的文档
manager.AddDocument(new TextDocument("报告.txt"));
manager.AddDocument(new ImageDocument("图表.jpg", 1920, 1080, "JPEG"));
manager.AddDocument(new PdfDocument("手册.pdf", 25));
manager.AddDocument(new TextDocument("笔记.txt"));
Console.WriteLine();
// 使用多态操作文档
manager.OpenAllDocuments();
Console.WriteLine();
manager.ShowDocumentStatistics();
Console.WriteLine();
manager.EditTextDocuments("这是追加的内容。");
Console.WriteLine();
manager.SaveAllDocuments();
Console.WriteLine();
manager.PrintAllDocuments();
manager.ExportAllToHtml("C:\\Exports");
Console.WriteLine();
// 演示特定类型的操作
Console.WriteLine("=== 特定操作演示 ===");
var textDoc = new TextDocument("新文档.txt");
textDoc.Open();
textDoc.SetContent("这是新的文档内容。");
textDoc.AppendContent("\n这是追加的内容。");
textDoc.PrintPreview();
textDoc.Save();
}本章小结
本章详细介绍了 C# 中的多态:
关键要点:
- 多态定义:同一接口的多种实现,"一个接口,多种形态"
- 多态类型:编译时多态(重载)和运行时多态(重写)
- 实现方式:虚方法重写、抽象方法实现、接口实现
- 多态优势:代码灵活性、可扩展性、可维护性
多态的实现机制:
- 虚方法表(VMT):运行时方法分派
- 后期绑定:运行时确定调用的方法
- 类型检查:is 和 as 操作符
设计模式应用:
- 策略模式:不同算法的多态实现
- 模板方法模式:定义算法骨架,子类实现细节
- 工厂模式:多态创建对象
最佳实践:
- 面向接口编程,而不是面向实现
- 合理使用抽象类和接口
- 避免过度使用继承,考虑组合
- 使用多态简化客户端代码
- 遵循里氏替换原则
多态的好处:
- 代码重用:统一的接口处理不同对象
- 扩展性:添加新类型无需修改现有代码
- 维护性:修改实现不影响客户端
- 灵活性:运行时决定具体行为
注意事项:
- 虚方法调用有性能开销
- 过度使用多态可能降低代码可读性
- 注意接口设计的稳定性
- 合理使用 sealed 关键字
下一步: 在下一章中,我们将学习接口,深入理解 C# 中接口的定义、实现和应用。