多态 #
一、多态概述 #
多态是指同一操作作用于不同对象时,产生不同的行为。C#支持两种多态:
| 类型 | 说明 |
|---|---|
| 编译时多态 | 方法重载、运算符重载 |
| 运行时多态 | 虚方法、抽象方法、接口 |
二、编译时多态 #
2.1 方法重载 #
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;
}
var calc = new Calculator();
calc.Add(1, 2);
calc.Add(1.5, 2.5);
calc.Add(1, 2, 3);
calc.Add("Hello", "World");
2.2 运算符重载 #
csharp
public struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public static Point operator +(Point a, Point b)
=> new Point(a.X + b.X, a.Y + b.Y);
public static Point operator -(Point a, Point b)
=> new Point(a.X - b.X, a.Y - b.Y);
public static bool operator ==(Point a, Point b)
=> a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b)
=> !(a == b);
public override string ToString() => $"({X}, {Y})";
}
var p1 = new Point(1, 2);
var p2 = new Point(3, 4);
var p3 = p1 + p2;
三、运行时多态 #
3.1 虚方法 #
csharp
public class Animal
{
public string Name { get; set; }
public virtual void MakeSound()
{
Console.WriteLine("动物发出声音");
}
public virtual string GetInfo()
{
return $"动物:{Name}";
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("汪汪汪");
}
public override string GetInfo()
{
return $"狗:{Name}";
}
}
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("喵喵喵");
}
public override string GetInfo()
{
return $"猫:{Name}";
}
}
3.2 多态调用 #
csharp
Animal animal1 = new Dog { Name = "旺财" };
Animal animal2 = new Cat { Name = "咪咪" };
animal1.MakeSound();
animal2.MakeSound();
Console.WriteLine(animal1.GetInfo());
Console.WriteLine(animal2.GetInfo());
3.3 集合中的多态 #
csharp
var animals = new List<Animal>
{
new Dog { Name = "旺财" },
new Cat { Name = "咪咪" },
new Dog { Name = "大黄" }
};
foreach (var animal in animals)
{
animal.MakeSound();
}
四、抽象类多态 #
4.1 抽象类定义 #
csharp
public abstract class Shape
{
public string Name => GetType().Name;
public abstract double Area { get; }
public abstract double Perimeter { get; }
public virtual void Display()
{
Console.WriteLine($"{Name}: 面积={Area:F2}, 周长={Perimeter:F2}");
}
}
4.2 具体实现 #
csharp
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override double Area => Width * Height;
public override double Perimeter => 2 * (Width + Height);
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double Area => Math.PI * Radius * Radius;
public override double Perimeter => 2 * Math.PI * Radius;
}
public class Triangle : Shape
{
public double A { get; set; }
public double B { get; set; }
public double C { get; set; }
public override double Area
{
get
{
double s = Perimeter / 2;
return Math.Sqrt(s * (s - A) * (s - B) * (s - C));
}
}
public override double Perimeter => A + B + C;
}
4.3 使用多态 #
csharp
var shapes = new List<Shape>
{
new Rectangle { Width = 5, Height = 3 },
new Circle { Radius = 4 },
new Triangle { A = 3, B = 4, C = 5 }
};
double totalArea = 0;
foreach (var shape in shapes)
{
shape.Display();
totalArea += shape.Area;
}
Console.WriteLine($"总面积:{totalArea:F2}");
五、接口多态 #
5.1 接口定义 #
csharp
public interface IDrawable
{
void Draw();
}
public interface IResizable
{
void Resize(double factor);
}
public interface IColorable
{
string Color { get; set; }
}
5.2 接口实现 #
csharp
public class Rectangle : Shape, IDrawable, IResizable, IColorable
{
public double Width { get; set; }
public double Height { get; set; }
public string Color { get; set; }
public override double Area => Width * Height;
public override double Perimeter => 2 * (Width + Height);
public void Draw()
{
Console.WriteLine($"绘制{Color}矩形 {Width}x{Height}");
}
public void Resize(double factor)
{
Width *= factor;
Height *= factor;
}
}
public class Circle : Shape, IDrawable, IColorable
{
public double Radius { get; set; }
public string Color { get; set; }
public override double Area => Math.PI * Radius * Radius;
public override double Perimeter => 2 * Math.PI * Radius;
public void Draw()
{
Console.WriteLine($"绘制{Color}圆形 半径{Radius}");
}
}
5.3 接口多态调用 #
csharp
var drawables = new List<IDrawable>
{
new Rectangle { Width = 5, Height = 3, Color = "红色" },
new Circle { Radius = 4, Color = "蓝色" }
};
foreach (var drawable in drawables)
{
drawable.Draw();
}
var resizables = new List<IResizable>
{
new Rectangle { Width = 5, Height = 3 },
};
foreach (var resizable in resizables)
{
resizable.Resize(2);
}
六、多态设计模式 #
6.1 策略模式 #
csharp
public interface IDiscountStrategy
{
decimal CalculateDiscount(decimal amount);
}
public class NoDiscount : IDiscountStrategy
{
public decimal CalculateDiscount(decimal amount) => 0;
}
public class PercentageDiscount : IDiscountStrategy
{
private readonly decimal _percentage;
public PercentageDiscount(decimal percentage) => _percentage = percentage;
public decimal CalculateDiscount(decimal amount) => amount * _percentage / 100;
}
public class FixedDiscount : IDiscountStrategy
{
private readonly decimal _fixedAmount;
public FixedDiscount(decimal fixedAmount) => _fixedAmount = fixedAmount;
public decimal CalculateDiscount(decimal amount) => Math.Min(_fixedAmount, amount);
}
public class PriceCalculator
{
private IDiscountStrategy _discountStrategy;
public PriceCalculator(IDiscountStrategy strategy)
{
_discountStrategy = strategy;
}
public void SetStrategy(IDiscountStrategy strategy)
{
_discountStrategy = strategy;
}
public decimal CalculateFinalPrice(decimal originalPrice)
{
return originalPrice - _discountStrategy.CalculateDiscount(originalPrice);
}
}
6.2 工厂模式 #
csharp
public abstract class Document
{
public abstract void Open();
public abstract void Save();
}
public class WordDocument : Document
{
public override void Open() => Console.WriteLine("打开Word文档");
public override void Save() => Console.WriteLine("保存Word文档");
}
public class PdfDocument : Document
{
public override void Open() => Console.WriteLine("打开PDF文档");
public override void Save() => Console.WriteLine("保存PDF文档");
}
public class ExcelDocument : Document
{
public override void Open() => Console.WriteLine("打开Excel文档");
public override void Save() => Console.WriteLine("保存Excel文档");
}
public static class DocumentFactory
{
public static Document Create(string type)
{
return type.ToLower() switch
{
"word" => new WordDocument(),
"pdf" => new PdfDocument(),
"excel" => new ExcelDocument(),
_ => throw new ArgumentException($"未知文档类型:{type}")
};
}
}
Document doc = DocumentFactory.Create("word");
doc.Open();
doc.Save();
七、实战示例 #
7.1 支付系统 #
csharp
public interface IPaymentMethod
{
bool ProcessPayment(decimal amount);
string Name { get; }
}
public class CreditCardPayment : IPaymentMethod
{
public string Name => "信用卡";
public string CardNumber { get; set; }
public bool ProcessPayment(decimal amount)
{
Console.WriteLine($"信用卡支付:{amount:C}");
return true;
}
}
public class WeChatPayment : IPaymentMethod
{
public string Name => "微信支付";
public bool ProcessPayment(decimal amount)
{
Console.WriteLine($"微信支付:{amount:C}");
return true;
}
}
public class AlipayPayment : IPaymentMethod
{
public string Name => "支付宝";
public bool ProcessPayment(decimal amount)
{
Console.WriteLine($"支付宝支付:{amount:C}");
return true;
}
}
public class PaymentProcessor
{
private readonly List<IPaymentMethod> _methods = new();
public void AddMethod(IPaymentMethod method) => _methods.Add(method);
public IEnumerable<string> GetAvailableMethods() => _methods.Select(m => m.Name);
public bool Process(string methodName, decimal amount)
{
var method = _methods.FirstOrDefault(m => m.Name == methodName);
return method?.ProcessPayment(amount) ?? false;
}
}
八、总结 #
多态要点:
| 类型 | 说明 |
|---|---|
| 编译时多态 | 重载 |
| 运行时多态 | 虚方法、抽象类、接口 |
| virtual/override | 虚方法重写 |
| abstract | 抽象方法强制实现 |
下一步,让我们学习抽象类!
最后更新:2026-03-26