一、什么是多态?

多态是面向对象三大特性封装、继承、多态最能体现代码灵活度的特性。

多态定义:同一个方法,不同对象,表现出不同行为。

通俗比喻:

  • 同样是“叫”这个动作:狗是汪汪叫、猫是喵喵叫、鸡是咯咯叫。
  • 动作名称统一,但具体行为由子类自己决定,这就是多态。

官方本质:父类引用指向子类对象,运行时执行子类重写的逻辑

二、为什么需要多态?

如果没有多态,我们会出现大量 if/else 判断,代码臃肿、难扩展。

多态的核心价值:

  • 统一调用入口:父类统一调用,不用管具体是哪个子类。
  • 开闭原则:新增子类不用改原有业务代码,直接扩展。
  • 代码解耦:调用层和具体实现层分离。

三、C# 多态两种实现方式

C# 多态分为两类:

  • 虚方法多态(virtual + override:父类有默认实现,子类可重写
  • 抽象类多态(abstract:父类无实现,强制子类重写

1. 虚方法多态(最常用、项目最多)

关键字:

  • virtual:父类允许子类重写
  • override:子类重写父类虚方法

完整实战代码

// 父类
public class Animal
{
    // 虚方法:允许子类重写
    public virtual void Cry()
    {
        Console.WriteLine("动物发出叫声");
    }
}

// 子类猫
public class Cat : Animal
{
    // 重写实现自己的逻辑
    public override void Cry()
    {
        Console.WriteLine("喵喵喵");
    }
}

// 子类狗
public class Dog : Animal
{
    public override void Cry()
    {
        Console.WriteLine("汪汪汪");
    }
}

 

多态调用(核心写法)

// 父类引用 指向 子类对象 = 多态
Animal a1 = new Cat();
Animal a2 = new Dog();

a1.Cry(); // 喵喵喵
a2.Cry(); // 汪汪汪

 

关键点:编译看父类,运行看子类

2. 抽象类多态(强制规范)

当父类方法没有通用逻辑,必须子类自己实现时,用抽象多态。

特点:

  • 抽象方法无方法体
  • 子类必须全部重写,否则报错
  • 抽象类不能 new 实例

抽象多态代码

public abstract class Animal
{
    //
抽象方法:无实现,强制子类重写
    public abstract void Cry();
}

public class Cat : Animal
{
    public override void Cry()
    {
        Console.WriteLine("喵喵喵");
    }
}

public class Dog : Animal
{
    public override void Cry()
    {
        Console.WriteLine("汪汪汪");
    }
}

 

四、面试高频:override new 的区别

很多新手踩坑:子类写同名方法不加 override,默认是 new 隐藏没有多态

关键字

多态支持

执行方式

场景

override

✅ 真正多态

运行时执行子类方法

重写逻辑、统一行为

new

❌ 无多态

编译时绑定父类方法

隐藏父类,不推荐多用

五、面向对象三大特性——总结

  • 封装:藏细节、暴接口。将类的内部字段、私有逻辑全部隐藏起来,不允许外部随意修改,只对外暴露安全的公共属性和方法,既能保护数据安全、避免数据错乱,又能简化外部调用,使用者无需关注内部复杂实现。

  • 继承:复用代码、减少重复。子类可以直接继承父类已有的属性和方法,无需重复编写相同代码,极大减少代码冗余,统一代码规范,同时可以在父类基础上扩展新功能,提升代码复用性和维护性。

  • 多态:统一调用、灵活扩展、解耦代码。基于继承和重写,实现“一个方法名称,多种执行效果”,对外提供统一的调用入口,无需修改原有代码就能扩展新功能,彻底解除代码耦合,让项目代码更灵活、易迭代、易维护,是企业开发架构设计的核心基础。

六、核心口诀

父类引用指向子类对象,虚方法重写实现多态,编译看父类,运行看子类。

更多推荐