一、概念
多态作为面向对象编程的另一个核心概念,允许基类引用在运行时根据其指向的实际对象类型,调用不同子类的具体实现。
1. 静态多态(静态时绑定)
在编译阶段确定具体调用的方法,绑定发生在编译期。
主要依靠函数重载和运算符重载来实现。
(1)函数重载(Function Overloading):
在同一个作用域中(通常是一个类内部),允许多个方法共享相同的名称,但这些方法必须具有不同的参数列表。编译器根据调用时提供的实际参数数量、类型和顺序,自动选择最匹配的方法实现执行。
数量不同: 一个方法接受1个参数,另一个接受2个参数;
类型不同:一个方法接受int,另一个接受double;
顺序不同: 一个方法接受(int, string),另一个接受(string, int)(注意:仅当类型组合能明确区分时才有意义)。
eg:
using System;
namespace Function
{
public class Calculator
{
// 功能1:处理整数相加
public int Add(int a, int b)
{
// 返回计算结果
return a + b;
}
// 功能2:处理浮点数和整数相加
public double Add(int a, double b)
{
return a + b;
}
// 功能3:处理三个数相加
public int Add(int a, int b, int c)
{
return a + b + c;
}
}
class Program
{
static void Main()
{
Calculator calc = new Calculator();
// 两个整数相加
int num1 = 2, num2 = 3;
int result1 = calc.Add(num1, num2);
Console.WriteLine($"整数相加: {num1} + {num2} = {result1}");
// 一个小数和一个整数相加
int a1 = 1;
double d2 = 2.5;
double result2 = calc.Add(a1, d2);
Console.WriteLine($"小数相加: {a1} + {d2} = {result2}");
// 三个整数相加
int n1 = 1, n2 = 2, n3 = 3;
int result3 = calc.Add(n1, n2, n3);
Console.WriteLine($"三个数相加: {n1} + {n2} + {n3} = {result3}");
Console.ReadKey();
}
}
}
(2)运算符重载(Operator Overloading):
允许为自定义类型(类或结构体)重新定义内置运算符(如 +, ==, > 等)的语义。通过静态方法实现,编译器根据操作数的类型在编译时绑定到自定义实现。
语法:
public static [返回类型] operator [运算符符号] (操作数参数)
{
return new [返回类型] //返回新对象为了避免修改原始值
}
eg:
using System;
namespace Example
{
public struct Complex
{
public double Real { get; }
public double Imaginary { get; }
//构造函数 创建新的复数对象
public Complex(double real, double imaginary)
{
Real = real;
Imaginary = imaginary;
}
// 核心:运算符重载
public static Complex operator +(Complex a, Complex b)
{
return new Complex(a.Real + b.Real, a.Imaginary + b.Imaginary);
}
}
class Program
{
static void Main(string[]args)
{
// 创建两个复数
Complex c1 = new Complex(3, 4);
Complex c2 = new Complex(1, 2);
// 使用重载的 + 运算符
Complex result = c1 + c2;
// 直接输出属性值
Console.WriteLine($"结果: {result.Real} + {result.Imaginary}i");
Console.ReadKey();
}
}
}
通过 new 运算符调用构造函数创建复数对象c1和c2,然后使用重载后的“+”运算,使两个对象按照重载函数中的运算进行,最终返回一个新的复数对象。
2. 动态多态(运行时绑定)
在程序运行阶段才能确定具体调用哪个函数实现的多态。主要通过继承和虚函数来实现。
eg:
using System;
namespace RuntimePolymorphismDemo
{
public class Vehicle
{
public virtual void StartEngine()
{
Console.WriteLine("车辆启动:默认点火方式");
}
}
public class Car : Vehicle
{
public override void StartEngine()
{
Console.WriteLine("轿车启动:钥匙点火 | 安静无声");
}
}
public class Truck : Vehicle
{
public override void StartEngine()
{
Console.WriteLine("卡车启动:气压启动 | 轰鸣声");
}
}
public class ElectricCar : Vehicle
{
// 故意不重写,展示继承默认行为
}
class Program
{
static void Main(string[] args)
{
// 多态集合:统一用基类引用存放不同子类
Vehicle[] garage = {
new Car(),
new Truck(),
new ElectricCar()
};
// 多态调用:自动选择正确实现
foreach (Vehicle v in garage)
{
Console.Write($"{v.GetType().Name}的启动: ");
v.StartEngine(); // 运行时决定调用哪个方法
}
/* 输出:
Car的启动: 轿车启动:钥匙点火 | 安静无声
Truck的启动: 卡车启动:气压启动 | 轰鸣声
ElectricCar的启动: 车辆启动:默认点火方式
*/
}
}
}
继承关系:子类继承父类,子类 : 父类
虚方法:父类用virtual声明可重写方法
重写:子类用override提供具体实现
foreach 循环:
foreach (Vehicle v in garage)
{
// 循环体
}
C#的循环结构,声明一个Vehicle类型名为v的变量,将garage数组中的每个元素,依次赋值给变量v,然后执行循环体。
实际赋值情况:
// 第一次循环
v = garage[0]; // 实际是Car对象(内存地址指向Car实例)
// 第二次循环
v = garage[1]; // 实际是Truck对象
// 第三次循环
v = garage[2]; // 实际是ElectricCar对象
评论前必须登录!
注册