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.多种形态,引用的多种形态对于一个引用变量,可以指向任何类的对象.对于一个父类的引用(类与类之间有一种继承关系),可以指向子类,也可以指向本类,指向的类型不同.当通过此引用向对象发送消息,调 ...
随机推荐
- 草珊瑚的css基础
首先要了解如下概念: viewport,窗口大小,containing block,block formatting context,inline formatting context,dirctio ...
- jQuery 中的children()和 find() 的区别
<!DOCTYPE html> <html> <head> <script type="text/javascript" src=&quo ...
- server-pc--------------->lspci,lsusb,meminfo等配置信息
安装yum install pciutils usbutils [root@server09 ~]# [root@server09 ~]# lspci00:00.0 Host bridge: Inte ...
- mysql概要(六)连接
内连接 [join on / from 表1,表二 ]效果一样 区别是:可以理解为首先取得笛卡儿积后,再 内连接:取俩表的匹配数据: 左连接:取的俩表匹配数据,并且保留未匹配数据中左表的数据,右表数据 ...
- iOS8 获取通知设置状态
UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSet ...
- [转载] 一致性问题和Raft一致性算法
原文: http://daizuozhuo.github.io/consensus-algorithm/ raft 协议确实比 paxos 协议好懂太多了. 一致性问题 一致性算法是用来解决一致性问题 ...
- Python IDE专用编辑器PyCharm下载及配置安装过程(Ubuntu环境)
这几天在折腾Python环境,显示把笔记本安装Ubuntu Linux环境系统,然后基本的Python环境都安装完毕之后需要安装传说中在其平台中最好的代码编辑和管理工具PyCharm,于是就根据网上的 ...
- apiCloud中图片裁剪模块FNImageClip的使用
思路 1.获取需裁剪图片的地址 2.跳转到裁剪页面 3.裁剪成功返回新图片地址 4.替换原有图片地址 增加修饰和事件 str += '<li class="tu image" ...
- (六)动手写第一个shell
1.编辑器.编译器.运行方法(脚本的3种执行方法)(1)shell程序是文本格式的,只要是文本编辑器都可以.但是因为我们的shell是要在linux系统下运行的,所以换行符必须是'\n',而windo ...
- WDS的原理
WDS的原理 WDS 即 Wireless Distribution System,是无线网络部署延展系统的简称,指用多个无线网络相互联结的方式构成一个整体的无线网络.简单地说,WDS就是利用两个(或 ...