关于虚方法virtual和抽象方法以及多态的研究

2023-10-26

虚方法virtual定义:    

当类中的方法声明前加上了virtual   修饰符,我们称之为虚方法,反之为非虚。使用了virtual   修饰符后,不允许再有static,   abstract,   或override 修饰符(必须是Public)。   为了实现多态,父类里面的方法用虚方法,子类里面可以对该方法重写,也可以不重写,当我们创建了一个子类 的对象并把它转换成了父类的类型后,如果子类里面没有重写父类里面的虚方法,则直接调用父类的方法,如果子类 里面重写了虚方法,则调用子类时面重写后的方法。

虚方法和非虚方法什么区别呢?

对于非虚的方法,无论被其所在类的实例调用,还是被这个类的派生类的实例调用,方法的执行方式不变对于虚方法它的执行方式可以被派生类改变,这种改变是通过方法的重载来实现的。举个例子(简单的代码):

 class A
 2     {
 3         public void F() { Console.WriteLine("A.F"); }
 4         public virtual void G() { Console.WriteLine("A.G"); }  //定义虚方法
 5     }
 6     class B : A
 7     {
 8         new public void F() { Console.WriteLine("B.F"); }      //这里的方法则不能重写,因为基类中的F()方法不是虚方法。
 9         public override void G() { Console.WriteLine("B.G"); }   //重写虚方法
10     }
11 static void Main(string[] args)
12         {        
18             B b = new B();
19             A a = b;      //A对象指向B对象
20             b.F();       //显示结果B.F
21             a.F();       //显示结果A.F
22             b.G();       //显示结果B.G 
23             a.G();       //显示结果B.G 实际这里调用的是不是基类中的G方法,而是派生类中重写过的G方法。
24             Console.ReadKey();
25         }
结果是:

B.F

A.F

B.G

B.G

a.G()的结果是B.G。这里了可以得出结论,当基类对象指向派生类对象时,基类的虚方法被重写,函数执行的是派生类方法。不是虚方法调用的是基类方法。

非虚拟方法的实现是不变的:无论是在声明它的类的实例上调用该方法还是在派生类的实例上调用,实现都是相同的。与此相反,虚拟方法的实现可以由派生类取代取代所继承的虚拟方法之实现的过程称为重写方法   

这里的new 是在子类对父类方法的一种替换,不写会有警告;

与抽象方法什么区别呢?

一、抽象方法的使用:
 1、方法前加abstract,同时在类前也要加abstract(必须要加),这个类称为抽象类,方法要是public。
 2、抽象方法不能实现,这里说的实现是指没有方法体,但是必须在非抽象子类里实现; 
 3、抽象方法在子类里一定要重写;
 4、任何一个非抽象子类必须要重写父类的抽象方法。
二、区别:
   1、抽象方法在父类里面一定不可以实现,即要有方法体(就是方法后面有没有大括号{ }),而虚方法在父类时面一定要带方法体;
   2、抽象方法在子类里面一定要实现,虚方法在子类里面可以不用重写,也可以重写(重写要实现)。二者都可以看做多态的范畴,这些多用在设计模式上写大型的游戏时多用在搭框架。  C#中写方法的时候,除了接口和抽象方法,其它的基本都带方法体

这两者都是多态的范畴,多态怎么理解?

  多态是我们在写方法时,为了使代码的重用性达到最大,通常都会把子类的对象转换成父类,但是在调方法时只能调到父类里面的方法,而子类里面的方法调不到,但是每个子类又有各自的行为,此时用到多态,子类时面重写父类里面的方法,,但子类在调同一个方法时,都会调到各自重写的方法,这样类型也达到了统一,处理起来也方法,同时也体现了子类 的各自的行为.(粗糙的说多态是和重写方法同时出现的,因为重写了就实现了多态,如果不重写,所有的子类调用父类的虚方法都是一样的,但是这样的话不要说出来,自己理解可以这样理解 ,说出来别人会认为你外行了。)
  另外接口也可以实现多态,多个类继承一个接口,各自类进行不同的实现后,不同的类调用接口里面的方法 ,这样也实现了多态。虚方法,抽象 方法和接口都可以实现多态,设计模式里面大多用到接口。

重写的概念:

是子类(即派生类)的方法覆盖父类(即基类)的虚方法。

   重写的要求:

1、三相同:

(1)方法名称相同

(2)参数列表相同

(3)返回值类型相同

一句话,只需重写代码体的内容!

2、重写声明不能更改虚方法的可访问性:重写方法和虚方法必须具有相同的访问级修饰符。例如:虚方法为public的,重新方法也必须是public的。

3、可以重写基方法:必须是虚拟的(virtual)、抽象的(abstract)或重写的(override)。(非虚方法或静态方法是不可以重写的)。

4、不能使用下列修饰符修改重写(override)方法(即该方法中含有override关键字):new、static、virtual、abstract

如:new public override void outwork () //这样写是不可以的

{

      MessageBox.Show("子类的子类(override)下班");

}

5、重写属性:重写的属性必须与继承属性有完全相同的访问修饰符、类型和属性名,并且重写属性必须是虚拟的(virtual)、抽象的(abstract)或是重写的(override)。

6、new关键字和override关键字比较:

        如果使用override重写xx方法,通过父类引用一样只能看到重写后的方法; override重写的是虚方法,那么就只剩下重写以后的方法,原来的方法被覆盖了。如果使用new隐藏xx方法,父类子类引用各自对应方法;new隐藏基类的方法,那么基类的方法和当前类的方法同时存在只是被隐藏了。

总结:override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已。



 


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于虚方法virtual和抽象方法以及多态的研究 的相关文章

随机推荐

  • web安全--环境搭建

    1 搭建环境 下载owasp靶机测试环境 login root password owaspbwa 下载kali linux攻击机也可以使用windows作为攻击机 我的是2020 login kaili password kali 其他版
  • typescript学习(二)——函数

    一 函数的定义 1 函数声明法 规定返回值必须为string类型 function run string return im string 2 匿名函数法 let run function string return im string 没
  • uniapp实现下拉加载更多 u-loadmore

    区别于官网教程 这里总结更为白话 要实现的需求是 比如起初有十条数据 下拉至底部 追加某数量的数据 比如我的项目中 我把它放在了数据展示的底部 上代码
  • 微信支付踩坑记-签名错误,请检查后再试

    注册商户号 使用微信支付功能 直接无脑设置v3密钥 然后配合wxjava这个包进行开发 结果试了很多遍 都报错 最后才发现 我一直使用的v2验证方式 之前都没有设置过v2密钥 最后把v2密钥设置成和v3一样 重新试了一下 解决问题 最后附上
  • Python3学习(六):函数

    Python3 函数 函数是组织好的 可重复使用的 用来实现单一 或相关联功能的代码段 函数能提高应用的模块性 和代码的重复利用率 你已经知道Python提供了许多内建函数 比如print 但你也可以自己创建函数 这被叫做用户自定义函数 可
  • 广度优先算法

    deque 即双端队列 是一种具有队列和栈的性质的数据结构 双端队列中的元素可以从两端弹出 其限定插入和删除操作在表的两端进行 最短路径问题的算法被称为广度优先搜索 广度优先搜索是一种用于图的查找算法 第一类问题 从节点A出发 有前往节点B
  • Pandas 写入 Excel 的几种情形与方式,覆盖,新增,追加,对齐

    Pandas 写入 Excel 的几种情形与方式 覆盖 新增 追加 对齐 以下代码默认已经导入 np pd import numpy as np import pandas as pd 执行下面示例之前 最好先删除 test xlsx 文件
  • 怎样去掉PATH中重复的项目

    在zsh shell 中输入 typeset U path 运行即可
  • IDEA中TDengine数据库连接

    过程描述 首先配置数据库连接信息 下载驱动jar包 配置驱动 Maven Repository com taosdata jdbc taos jdbcdriver mvnrepository com 下载 TDengine Client 安
  • Java web小项目_个人主页(1)—— 云环境搭建与项目部署

    摘自 Java web小项目 个人主页 1 云环境搭建与项目部署 作者 丶PURSUING 发布时间 2021 03 26 23 59 39 网址 https blog csdn net weixin 44742824 article de
  • Git & Github 的使用(配合VSCode)

    1 git 和 vscode 环境管理 git下载位置 根据自己的电脑配置进行下载即可 Git Downloads 比如我的是linux ubuntu 那么我就选择Linux 并在命令行下敲下来这个 下载完git后 可以在终端上输入命令 g
  • Junit

    TestCase之间一定要保持完全的独立性 不允许出现任何的依赖关系 不能依赖与测试方法的执行顺序 DRY Don t Repeat Yourself Junit一旦执行到了Assert fail 方法测试便失败
  • 五分钟搞懂 React Hooks 工作原理

    前言 Hooks 是 React 中比较火的一个概念 用过的小伙伴都说好 但是 在使用 Hooks 的时候 我们可能会有很多疑惑 1 为什么 useEffect 第二个参数是空数组 就相当于 ComponentDidMount 只会执行一次
  • hexo stellar博客设置Twikoo评论(使用Zeabur 部署)

    2023年7月24日更新 需要绑定一下支付宝 每个月大约4块钱 还算对学生党划算 否则可能无法使用免费的服务 说是免费额度结果还是要钱鸭 这里按要求开通就好了 主要参考 stellar 评论插件配置 Twikoo 这里使用的是Twikoo
  • i love you 浪漫字体复制_七夕

    七夕情人节来临之际 朋友圈早已被各种代购刷屏 你啥都不送 让你女朋友七夕的时候在朋友圈炫耀什么 扫一扫进七夕保命群 教你七夕买什么送女友才能保命 你男朋友是不是以为你缺氧 所以每个节日都送你空气 不得不承认他们一个个都是被代购事业耽误的网络
  • Towards 3D Human Pose Estimation in the Wild: a Weakly-supervised Approach论文翻译

    论文地址 https arxiv org abs 1704 02447 code https github com xingyizhou pytorch pose hg 3d Towards 3D Human Pose Estimation
  • 【机器学习】浅谈 模型大小与推理速度

    目录 一 前言 二 常用模型大小评估指标 2 1 计算量 2 2 参数量 2 3 访存量 2 4 内存占用 2 5 小结 三 计算量越小 模型推理就越快吗 3 1 计算密度与 RoofLine 模型 3 2 计算密集型算子与访存密集型算子
  • 逍遥模拟器导出文件到电脑

    1 确保已经成功连接模拟器 如有问题 请查看 https blog csdn net qq 15228737 article details 81142905 2 用cd命令找到要导出的文件夹 文件 再将该文件夹 文件导出到电脑上 如下图
  • React学习--JSX与react事件

    1 JSX 1 1 表达式 在React中使用JSX来描述HTML页面 而且可以与js混合使用 使用JavaScript表达式时要将表达式包含在大括号里 const user firstName Harper lastName Perez
  • 关于虚方法virtual和抽象方法以及多态的研究

    虚方法virtual定义 当类中的方法声明前加上了virtual 修饰符 我们称之为虚方法 反之为非虚 使用了virtual 修饰符后 不允许再有static abstract 或override 修饰符 必须是Public 为了实现多态