Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C#进阶学习--虚方法(virtual)

C#进阶学习--虚方法(virtual)

原创
作者头像
腾云大使
发布于 2022-01-11 12:36:48
发布于 2022-01-11 12:36:48
8500
举报

一.定义

简单的说,虚方法就是可以被子类重写的方法,如果子类重写了虚方法,那么运行时将使用重写后的逻辑,如果没有重写,则使用父类中虚方法的逻辑。
定义关键字:virtual
重写关键字:override

二.实例

定义一个Person类与Person类的Student子类,如下:

代码语言:C#
AI代码解释
复制
 public class Person
    {
        public string  Name { get; set; }

        public virtual int Age { get; set; }

        public virtual void SayHello()
        {
            Console.WriteLine("大家好,我是"+this.Name+" 年龄"+this.Age);
        }
        public virtual int Add(int a)
        {
            return this.Age+a;
        }
    }
假设现在学生类有如下需求:
1.需要在SayHello方法中增加学号的返回
2.需要对年龄做出校验,当年龄大于18岁时,直接返回18
代码语言:C#
AI代码解释
复制
  public class Student:Person
    {
        public string StuNO { get; set; }

        public override int Age
        {
            get => base.Age;            
            set => base.Age = value>18?18:value;
        }
        public override void SayHello()
        {
            Console.WriteLine("大家好,我是" + this.Name+",年龄"+this.Age+",我的学号是"+this.StuNO);
        }

    }

我们看到,针对需求1和2,重写了Age属性与SayHello方法,在控制台调用SayHello方法,调用方法如下:

代码语言:C#
AI代码解释
复制
 Person person = new Person();
 person.Name = "人";
 person.Age = 25;
 person.SayHello(); 

 Student student = new Student();
 student.Name = "学生";
 student.Age = 25;//这里的年龄大于18
 student.StuNO = "001";
 student.SayHello();

结果如下图:

这个时候,我们在Student类中增加一个Add方法(不是重写),然后再重写父类中的Add方法,如下:

代码语言:C#
AI代码解释
复制
  public int Add(int a,int b) //这个是新方法,表明覆盖父类里的同名类,而不是重新实现
        {
            return this.Age + a + 10;
        }

        public override int Add(int a)  //这个是重写的父类中的Add方法
        {
            return base.Add(a)+666;
        }

这时,在控制台调用Add方法时,如果采用两个参数,则执行新方法,如果采用一个参数,则执行重写方法。

如果采用子类实例化父类的方式,如下:

代码语言:C#
AI代码解释
复制
Person aaa = new Student();
aaa.SayHello();

通过验证,我们会发现,这时的SayHello执行的是子类中重写的SayHello方法

关于子类与父类虚方法的实现顺序,在这里直接给出前人的总结:

1、当调用一个对象的函数时,系统会直接去检查这个对象申明定义的类,即申明类,看所调用的函数是否为虚函数;
2、如果不是虚函数,那么它就直接执行该函数。而如果有virtual关键字,也就是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是转去检查对象的实例类。
3、在这个实例类里,他会检查这个实例类的定义中是否有重新实现该虚函数(通过override关键字),如果是有,那么OK,它就不会再找了,而马上执行该实例类中的这个重新实现的函数。而如果没有的话,系统就会不停地往上找实例类的父类,并对父类重复刚才在实例类里的检查,直到找到第一个重载了该虚函数的父类为止,然后执行该父类里重载后的函数。

至此,虚方法的总结结束......

最后,其实所有的数据测试可以在云服务器进行,大家可以看看腾讯云的相关服务,买来作为测试数据的服务器非常不错

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Java 学习】:抽象类&接口
💢💢在Java中,一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。
IsLand1314
2024/10/15
1730
【Java 学习】:抽象类&接口
C#进阶学习--抽象方法(abstract)
最后,其实所有的数据测试可以在云服务器进行,大家可以看看腾讯云的相关服务,买来作为测试数据的服务器非常不错,最低只要38一年
腾云大使
2022/01/12
9960
C#简单的面试题目(三)
31.C#提供一个默认的无参构造函数,当我实现了另外一个有一个参数的构造函数时,还想保留这个无参数的构 造函数。这样我应该写几个构造函数?     两个,一旦你实现了一个构造函数,C#就不会再提供默认的构造函数了,所以需要手动实现那个无参构造函数。
aehyok
2018/09/11
9920
C++基础语法简单介绍(二) -- C with classess
用户10859876
2025/01/15
1040
21天学习挑战赛之Java面向对象进阶
​ 子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化,原因在于,每一个子类构造方法的第一条语句默认都是:super()
楠羽
2022/11/18
2370
C#中虚方法(virtual)详解
当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法,虚方法是使用关键字virtual声明的,虚方法可以在不同的继承类中有不同的实现,即为基类中定义的允许在派生类中重写的方法;
全栈程序员站长
2022/10/03
7400
C#中虚方法(virtual)详解
C#基础知识系列七(base、this、new、override、abstract、virtual、static)
本文主要来讲解一下C#中,自己觉得掌握的不怎么样或者用的不多,不太熟悉的关键字,主要包括base、this、new、override、abstract、virtual以及针对static字段和static构造函数之间的执行问题。
aehyok
2018/08/31
6760
C#基础知识系列七(base、this、new、override、abstract、virtual、static)
A4第四章第2节null和成员变量、局部变量的不同初始化
A4第四章第2节null和成员变量、局部变量的不同初始化第4节 1、null表示变量没有指向任何对象 如:Person p=null; p.sayHello();//结果会抛出异常 2、对于一个为【null的变量】调用【成员方法】都会报异常NullReferenceException。
静心物语313
2020/03/24
5610
C++-面向对象(五)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
cwl_java
2019/10/28
3110
C++-面向对象(五)
ECMAScript中类与继承详解(Java对比学习)
如果声明一个一个类的时候没有声明构造函数,那么会默认添加一个空的构造函数,构造函数在new实例化一个对象的时候会被调用
coder_koala
2019/07/30
4470
面试官问我多态,我是这么回答的
多态涵盖的内容还是比较广泛的,总体可归纳如下图所示,可知多态主要分为静态多态和动态多态。两者的分类依据为多态的决定时机,静态多态由编译期决定,而动态多态由运行期决定。
程序员的园
2024/07/18
770
面试官问我多态,我是这么回答的
【C++进阶】继承
继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在保持原有类特性的基础上进行扩展,增加方法(成员函数)和属性(成员变量),这样产生新的类,称子类。 继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的函数层次的复用,继承是类设计层次的复用。
_小羊_
2024/10/16
860
【C++进阶】继承
Java——类与对象
<1>Class.forName("com.example.Student"),参数为类的全限定路径。
用户11453640
2025/01/17
960
C#中的override和new关键字
这是因为Java中的类方法默认是虚函数(虽然Java中没有这个叫法),子类函数会默认覆盖父类的同名函数(Java后来提供了@override注解)。然而C#中必须使用virtual关键字显示声明该函数是虚函数,然后在子类中使用override关键字重写父类方法,这才真正实现了对父类方法的重写,才能实现多态(C++中的多态就是使用虚函数实现的,而且和C#一样必须使用virtual关键字显示声明)。
卡尔曼和玻尔兹曼谁曼
2019/01/22
1.3K0
从父类到子类:C++ 继承的奇妙旅程(1)
        在前文,小编讲述了C++模板的进阶内容,下面我们就要结束C++初阶的旅行,开始进入C++进阶容的旅c程,今天旅程的第一站就是C++三大特性之一——继承的旅程,各位扶好扶手,开始我们今天的C++继承的奇妙旅程。
用户11295429
2025/05/09
670
从父类到子类:C++ 继承的奇妙旅程(1)
实例讲解override和new的区别
一、override:Override关键字主要是提供派生类对基类方法的新实现。 1、不可以用于重写非虚方法和静态方法 2、与其配套使用的关键字是Virtual、abstract、Override。 3、不能使用修饰符 new、static、virtual 或 abstract 来修改 override 方法。 ---- 二、new:new关键字可以在派生类中隐藏基类的方法,也就说在使用派生类调用的方法是New关键字新定义出来的方法,而不是基类的方法。在不使用New关键字来隐藏基类方法也是可以的,编译器会出
小端
2018/04/16
9450
C++进阶:继承和多态
例如上面这串代码,注释掉的那部分 就是错的,因为基类的友元函数无法访问到派生类保护或者私有成员。
用户11305458
2024/10/09
1260
C++进阶:继承和多态
【C++】多态
这里子类Student的虚函数BuyTicket就对父类Person的虚函数BuyTicket进行了重写。
YIN_尹
2024/01/23
1620
【C++】多态
【C++】多态
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
zxctscl
2024/04/25
1120
【C++】多态
C#-笔记-多态-第四章
概念:让一个对象能够表现出多种状态(类型) 虚方法 关键字virtual override 步骤:将父类的方法标记为虚方法,使用关键字virtual,这个函数可以被子类重新写一个遍历。
用户9857551
2022/06/28
2730
相关推荐
【Java 学习】:抽象类&接口
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档