Tutorialsteacher

关注我们

文章
  • C#
  • C# 面向对象编程
  • ASP.NET Core
  • ASP.NET MVC
  • LINQ
  • 控制反转 (IoC)
  • Web API
  • JavaScript
  • TypeScript
  • jQuery
  • Angular 11
  • Node.js
  • D3.js
  • Sass
  • Python
  • Go lang
  • HTTPS (SSL)
  • 正则表达式
  • SQL
  • SQL Server
  • PostgreSQL
  • MongoDB
  • C# - 入门
  • C# - 版本历史
  • C# - 第一个程序
  • C# - 关键词
  • C# - 类和对象
  • C# - 命名空间
  • C# - 变量
  • C# - 隐式类型变量
  • C# - 数据类型
  • 数字
  • 字符串
  • DateTime
  • 结构体
  • 枚举
  • StringBuilder
  • 匿名类型
  • 动态类型
  • 可空类型
  • C# - 值类型和引用类型
  • C# - 接口
  • C# - 运算符
  • C# - if else 语句
  • C# - 三元运算符 ?
  • C# - Switch 语句
  • C# - For 循环
  • C# - While 循环
  • C# - Do-while 循环
  • C# - 分部类
  • C# - Static 关键字
  • C# - 数组
  • 多维数组
  • 交错数组
  • C# - 索引器
  • C# - 泛型
  • 泛型约束
  • C# - 集合
  • ArrayList
  • List
  • SortedList
  • Dictionary
  • Hashtable
  • Stack
  • Queue
  • C# - 元组
  • C# - 值元组
  • C# - 内置异常
  • 异常处理
  • throw 关键字
  • 自定义异常
  • C# - 委托
  • Func 委托
  • Action 委托
  • Predicate 委托
  • 匿名方法
  • C# - 事件
  • C# - 协变
  • C# - 扩展方法
  • C# - 流 I/O
  • C# - File 类
  • C# - FileInfo 类
  • C# - 对象初始化器
  • OOP - 概述
  • 面向对象编程
  • 抽象
  • 封装
  • 关联与组合
  • 继承
  • 多态
  • 方法重写
  • 方法隐藏
  • C# - SOLID 原则
  • 单一职责原则
  • 开闭原则
  • 里氏替换原则
  • 接口隔离原则
  • 依赖倒置原则
  • 设计模式
  • 单例模式
  • 抽象工厂模式
  • 工厂方法模式
Entity Framework Extensions - 提升 EF Core 9
  批量插入
  批量删除
  批量更新
  批量合并

运行时多态:方法重写

运行时多态也称为基于继承的多态或方法重写。

继承允许你将基类继承到派生类中,基类的所有公共成员都会自动成为派生类的成员。但是,你可以在派生类中重新定义基类的成员,以提供与基类不同的实现。这称为方法重写,也称为运行时多态。

在 C# 中,默认情况下,类的所有成员都是密封的,不能在派生类中重新定义。使用 virtual 关键字修饰基类的成员使其可重写,并在派生类中使用 override 关键字表示该基类成员在派生类中被重新定义。

示例:方法重写
class Person
{
    public virtual void Greet()
    {
        Console.WriteLine("Hi! I am a person.");
    }
}

class Employee : Person
{
    public override void Greet()
    {
        Console.WriteLine("Hello! I am an employee.");
    }
}

如你所见,Person 类中的 Greet() 方法是用 virtual 关键字定义的。这意味着该方法可以在派生类中使用 override 关键字重写。在 Employee 类中,Greet() 方法用 override 关键字重新定义。因此,派生类扩展了基类的方法。

现在问题来了,哪个方法会被调用,是基类的方法还是派生类的方法?这取决于对象的类型。你能猜出下面程序的输出吗?

示例:调用重写方法
Person p1 = new Person();
p1.Greet();

Person p2 = new Employee();
p2.Greet();

Employee emp = new Employee();
emp.Greet();
尝试一下
输出
I am a human! I am a Manager! I am a Manager!

C# 将根据对象的类型而不是变量的类型来调用方法。如果你创建一个 Person 类的对象,它将调用 Person 类的 Greet() 方法;如果你创建一个 Employee 类的对象,它将调用 Employee 类的 Greet() 方法,无论它被分配给哪种类型的变量。

正如你在上一章学到的,C# 编译器在编译时多态中决定调用哪个方法。在运行时多态中,它将在运行时根据对象的类型来决定。

要理解为什么方法重写被称为运行时多态,请看下面的例子。

示例:运行时多态
class Program
{
    public static void Display(Person p){ 
        p.Greet();
    }

    public static void Main()
    {
        Person p1 = new Person();
        Display(p1);
            
        Person p2 = new Employee();
        Display(p2);
            
        Employee emp = new Employee();
        Display(emp);
    }
}
输出
I am a human! I am the Manager! I am the Manager!

在上面的例子中,Display() 方法接受一个 Person 类型的参数。因此,当你调用 Display() 方法时,你可以传入 Person 类型或 Employee 类型的对象。Display() 方法在编译时不知道你传入的参数类型。它在运行时可以是任何类型。这就是为什么方法重写被称为运行时多态。

重写规则

  • 方法、属性、索引器或事件可以在派生类中被重写。
  • 静态方法不能被重写。
  • 基类方法必须使用 virtual 关键字,以表明这些方法可以被重写。
  • 派生类必须使用 override 关键字来重写基类方法。

了解更多关于 virtual 和 override 关键字的信息。

如果我们不使用 virtual 和 override 关键字,并在派生类中重新定义基类方法会发生什么?在下一章中学习。

TUTORIALSTEACHER.COM

TutorialsTeacher.com 是您权威的技术教程来源,旨在通过循序渐进的方法,指导您掌握各种网络和其他技术。

我们的内容旨在帮助所有学习者轻松快速地掌握技术。访问此平台即表示您已审阅并同意遵守我们的使用条款和隐私政策,这些条款和政策旨在保护您的体验和隐私权。

[email protected]

关于我们使用条款隐私政策
copywrite-symbol

2024 TutorialsTeacher.com. (v 1.2) 版权所有。