C#多态问题
为什么对这个感觉趣呢.因为以前写过两篇关于这个多态和重载混合起来很乱的调用情况分析,自从哪以后,我自认为随便乱写一些继承多态的代码都应该难不到我.但是今天看到一段代码有一个地方计算错误了,所以有必要写下来巩固一下,但是我之前总结的是没有问题的,今天就用以前总结的方法来看下面代码
代码来自 http://www.cnblogs.com/wangfupeng1988/p/3629312.html 博客
/// <summary>
/// Father类
/// </summary>
public class Father
{
public void DoWork()
{
Console.WriteLine("Father.DoWork()");
} //虚方法
public virtual void DoVirtualWork()
{
Console.WriteLine("Father.DoVirtualWork()");
} //虚方法
public virtual void DoVirtualAll()
{
Console.WriteLine("Father.DoVirtualAll()");
}
} /// <summary>
/// Son类
/// </summary>
public class Son : Father
{
//new
public new void DoWork()
{
Console.WriteLine("Son.DoWork()");
}
//new virtual
public new virtual void DoVirtualWork()
{
base.DoVirtualWork();
Console.WriteLine("Son.DoVirtualWork()");
}
//override
public override void DoVirtualAll()
{
Console.WriteLine("Son.DoVirtualAll()");
}
} /// <summary>
/// Grandson类
/// </summary>
public class Grandson : Son
{
public override void DoVirtualWork()
{
base.DoVirtualWork();
Console.WriteLine("Grandson.DoVirtualWork()");
} public override void DoVirtualAll()
{
base.DoVirtualAll();
Console.WriteLine("Grandson.DoVirtualAll()");
}
}
}
下面Main里面的代码是这样的
//
Father son = new Son();
son.DoWork();
son.DoVirtualWork();
son.DoVirtualAll();
//
Father aGrandson = new Grandson();
aGrandson.DoWork();
Console.WriteLine("#");
aGrandson.DoVirtualWork();
Console.WriteLine("#");
aGrandson.DoVirtualAll();
我添加了两个分隔符号,方便阅读
先来看第1段的调用,
1.son.DoWork() 先看这个是否满足多态的条件(有继承,有父类引用,有虚方法重写),由于这个方法没有重写,所以不表现出多态,所以子类的new方法DoWork()是不调用的,这里调用父类的DoWork();所以显示Father.DoWork();
2.son.DoVirtualWork();这里也用同样没有方法的重写,所以不表现多态,直接调用父类方法
3.son.DoVirtualAll(); 这里满足条件了,所以这里表现出多态,应该调用子类的方法
这一段结果与上面的分析一样,看下一段,这里我就出错了.
先看
1.aGrandson.DoWork();这没有重写,不表现多态,所以显示Father的方法
2.aGrandson.DoVirtualWork() 这里有重写,是多态,那么显示子类的方法? 问题就在这里等会来分析
3.aGrandson.DoVirtualAll() 这里有重写,是多态,那么调用子类的方法.
这里我们重点来看一下第2,3两个步聚,首先第2步,是存重写,但是重写的是Son的new virtual void DoVirtualWork()方法,所以这一条继承链断了,所以这一步认为是 有父类引用,有虚方法重写,但是没有继承,所以这里不表现多态,那么直接调用Father的方法
然后看第3步,这里是有重写,有父类引用,有没有继承呢?这里有因为Son里面的没有用new关键字,所以这里也还算比较标准的多态调用,其实这里在运行时才去找到Son的DoVitualAll()方法的,平时最多的情况认为Grandson的父类是Father(是从这里代码来看);
这里问题看完了,那我们看一下这个
Console.WriteLine("#");
Son ss = new Grandson();
ss.DoVirtualWork();
这里有继承,有父类引用,有重写,那么应该调子类的方法
所以调Grandson.DoVirtualWork();由于这个调了父类的,所以再调Son的方法,Son又调了Father的方法,所以结果是
Father.DoVirtualWork()
Son.DoVirtualWork()
Grandson.DoVirtualWork()
都显示出来,差不多写到这里吧,方法还是好用的,我感觉分清楚了这三个条件,这些还是可以角决的.包括加入一些方法重载,只要分清处多态系和非多态系那就是没有问题的.
总结:
1.多态的三个条件,满足就调多态系方法,不满足就正常的调用(这里就可以说是调自身的方法)
2.分清为什么文中的第2步new断开的是继承,而不是其它条件.
3.父类引用指向子类,不管中间有多少层,我们分析的时候要注意,这两层是最重要的,但是也要注意一下,中间是否有断继承这类的情况
C#多态问题的更多相关文章
- Java中的多态
1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal {public abstract void Say();} 子类: public class ...
- C# 工厂模式+虚方法(接口、抽象方法)实现多态
面向对象语言的三大特征之一就是多态,听起来多态比较抽象,简而言之就是同一行为针对不同对象得到不同的结果,同一对象,在不同的环境下得到不同的状态. 实例说明: 业务需求:实现一个打开文件的控制台程序的d ...
- C#非常重要基础之多态
前几天看了一位同志的博客,写的是关于他自己去支付宝面试的经历.过程大体是这样的:问答的时候,前面部分,作者都应答如流,说起自己经验如何之丰富,最后面试官问了作者一个问题:请简述多态的概念和作用.结果这 ...
- C++多态详解
多态是面向对象的程序设计的关键技术.多态:调用同一个函数名,可以根据需要但实现不同的功能.多态体现在两个方面,我们以前学过的编译时的多态性(函数重载)和现在我们这一章将要学习的运行时的多态性(虚函数) ...
- 【那些年关于java多态应用】
1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal { public abstract void Say();} 子类: public class ...
- JAVA多态
多态是指当系统A访问系统B的服务时,系统B可以通过多种方式来提供服务,而这一切对系统A是透明的.比如动物园的饲养员能够给各种各样的动物喂食.下图显示了饲养员Feeder,食物Food和动物Animal ...
- C#多态“说来也说”——逻辑层BLL中的多态使用
本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/p/5861842.html 昨天晚上,有个朋友说学了好久,依然没搞 ...
- java多态的理解
面向对象语言中的类有三个特征,封装.继承.多态.封装与继承很好理解,那什么是多态呢? 1.什么是多态? 多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同 ...
- java中如何实现多态
复习基础知识 多态,就是重载和重写.重载发生在一个类中.重写发生在子类,意思就是子类重写父类相同名称的方法.刚学语言有的东西,不必搞得那么清楚,只有知道怎么用就行了,有的问题你要想真正把它搞得很懂,短 ...
- OC多态
要点: 1.多种形态,引用的多种形态对于一个引用变量,可以指向任何类的对象.对于一个父类的引用(类与类之间有一种继承关系),可以指向子类,也可以指向本类,指向的类型不同.当通过此引用向对象发送消息,调 ...
随机推荐
- ALV详解:OO SALV
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- [SAP ABAP开发技术总结]搜索帮助Search Help (F4)
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- js addEventListener attachEvent
attachEvent方法,为某一事件附加其它的处理事件.(不支持Mozilla系列) addEventListener方法 用于 Mozilla系列 举例: document.getElementB ...
- iOS 推送消息长度
iOS最大推送消息长度 官方要求是256个字节 实际测试为1005个字节 在iPhone6上测试 锁屏时收到消息时只显示76个汉字,剩下的被隐藏 程序进入后台时只显示47个汉字,剩下的被隐藏
- JavaWeb学习总结(四)—ServletConfig和ServletContext
一.ServletConfig 1. ServletConfig介绍: ServletConfig是Servlet中的init()方法的参数类型,服务器会在调用init()方法时传递ServletCo ...
- DOS中文乱码解决
在中文Windows系统中,如果一个文本文件是UTF-8编码的,那么在CMD.exe命令行窗口(所谓的DOS窗口)中不能正确显示文件中的内容.在默认情况下,命令行窗口中使用的代码页是中文或者美国的,即 ...
- unsigned 整型实现无溢出运算
普通的 int 整型能表示的范围很有限,所以刷题时很多时候不得不用 long long 来存更大的数据.或者找出数列中某个只出现一次(或奇数次)的数(其余的数均出现两次 / 偶数次),用异或运算的经典 ...
- MySQL 定时器EVENT学习
原文:http://blog.csdn.net/lifuxiangcaohui/article/details/6583535 MySQL 定时器EVENT学习 MySQL从5.1开始支持event功 ...
- Excel 、数据库 一言不合就转换 (zhuan)
http://blog.csdn.net/marksinoberg/article/details/52280786 ***************************************** ...
- jquery select选中项 赋值
$("flag").attr("value",flag); $("#flag").find("option:selected&qu ...