C# 中 Overload(重载)与 Override(重写)的核心区别与实战解析

在 C# 面向对象编程(OOP)中,多态是三大核心特性之一(封装、继承、多态)。
而在实际编码过程中,Overload(重载)Override(重写) 是最常见、也最容易被混淆的两种“多态体现方式”。

很多初学者会遇到以下困惑:

  • 方法名一样,为什么有时能共存,有时却编译报错?

  • 明明调用的是同一个方法名,运行结果却不一样?

  • virtualoverride 到底解决了什么问题?

本文将从 定义 → 特性 → 代码 → 底层逻辑 → 易错点 五个层次,彻底讲清楚 重载 vs 重写 的本质区别。


一、Overload(重载):同一类内的「静态多态」

1. 什么是方法重载?

方法重载(Overload) 指的是:

同一个类中,定义多个方法名相同,但参数列表不同的方法。

参数列表不同可以体现在:

  • 参数个数不同

  • 参数类型不同

  • 参数顺序不同(不推荐,影响可读性)

⚠️ 注意
仅修改返回值类型,不能构成重载,否则会直接编译报错。


2. 重载的核心特性

重载的本质可以总结为三点:

  • 编译时多态(静态多态)
    在编译阶段,编译器就已经确定要调用哪个方法

  • 不依赖继承

  • 不需要任何关键字(virtual / override)

👉 核心目的

使用“同一个方法名”,适配“不同参数场景”,提升 API 的可读性与易用性。


3. 重载示例解析

class Shape
{
    // 无参数的 Draw
    public virtual void Draw()
    {
        Console.WriteLine("绘制一个形状");
    }

    // 带参数的 Draw —— 重载
    public void Draw(int size)
    {
        Console.WriteLine($"绘制一个大小为 {size} 的形状");
    }
}

调用时:

Shape shape = new Shape();

shape.Draw();     // 匹配 Draw()
shape.Draw(10);   // 匹配 Draw(int)

📌 关键点
调用哪个方法,完全由参数列表决定,与对象运行时类型无关。


二、Override(重写):父子类间的「动态多态」

1. 什么是方法重写?

方法重写(Override) 指的是:

子类对基类中 virtual / abstract 修饰的方法 进行重新实现。

重写必须满足以下条件:

  • ✔️ 存在继承关系

  • ✔️ 基类方法使用 virtualabstract

  • ✔️ 子类方法使用 override

  • ✔️ 方法签名 完全一致(方法名 + 参数列表 + 返回值)


2. 重写的核心特性

  • 运行时多态(动态多态)

  • 行为取决于对象的实际类型

  • ✅ 是 OOP 中多态的核心机制

👉 核心目的

允许子类在不改变调用方式的前提下,定制或替换父类的行为。


3. 重写示例解析

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("绘制一个圆形");
    }
}

关键调用代码:

Shape shape = new Circle();
shape.Draw();

📌 重点理解

  • 变量声明类型:Shape

  • 对象实际类型:Circle

  • 运行结果:调用 Circle.Draw()

这正是动态多态的体现。


三、Overload 与 Override 的核心区别对比

对比维度Overload(重载)Override(重写)
发生范围同一个类内部基类与子类之间
是否依赖继承❌ 不需要✅ 必须
方法名相同相同
参数列表必须不同必须完全一致
返回值不能仅靠返回值区分必须与基类一致
关键字virtual / override
多态类型编译时多态(静态)运行时多态(动态)
决定时机编译期运行期
核心用途适配不同参数定制父类行为

四、完整示例:重载 + 重写的组合使用

1. 完整可运行代码

using System;

class Shape
{
    // 可被重写的虚方法
    public virtual void Draw()
    {
        Console.WriteLine("绘制一个形状");
    }

    // 重载方法
    public void Draw(int size)
    {
        Console.WriteLine($"绘制一个大小为 {size} 的形状");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("绘制一个圆形");
    }
}

class Program
{
    static void Main()
    {
        Shape shape = new Shape();
        Circle circle = new Circle();

        shape.Draw();       // Shape.Draw()
        shape.Draw(10);     // Shape.Draw(int)

        shape = circle;
        shape.Draw();       // Circle.Draw()
    }
}

2. 程序运行结果

绘制一个形状
绘制一个大小为 10 的形状
绘制一个圆形

五、常见误区与踩坑总结

❌ 误区 1:仅修改返回值实现重载

int Foo();
string Foo(); // 编译错误

✔️ 原因:返回值不属于方法签名的一部分。


❌ 误区 2:基类没加 virtual,子类却 override

class A
{
    public void Test() {}
}

class B : A
{
    public override void Test() {} // 编译错误
}

❌ 误区 3:重写时修改参数列表

public override void Draw(int size) // ❌

❌ 误区 4:混淆声明类型与实际类型

Shape shape = new Circle();
shape.Draw();

👉 真正决定调用哪个方法的是:new Circle()


六、总结一句话记住区别

重载(Overload)
👉 同一个类中,方法名相同、参数不同编译期决定

重写(Override)
👉 父子类之间,方法签名一致、行为可替换运行期决定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcome_com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值