为什么对这个感觉趣呢.因为以前写过两篇关于这个多态和重载混合起来很乱的调用情况分析,自从哪以后,我自认为随便乱写一些继承多态的代码都应该难不到我.但是今天看到一段代码有一个地方计算错误了,所以有必要写下来巩固一下,但是我之前总结的是没有问题的,今天就用以前总结的方法来看下面代码

代码来自 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#多态问题的更多相关文章

  1. Java中的多态

    1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal {public abstract void Say();} 子类: public class ...

  2. C# 工厂模式+虚方法(接口、抽象方法)实现多态

    面向对象语言的三大特征之一就是多态,听起来多态比较抽象,简而言之就是同一行为针对不同对象得到不同的结果,同一对象,在不同的环境下得到不同的状态. 实例说明: 业务需求:实现一个打开文件的控制台程序的d ...

  3. C#非常重要基础之多态

    前几天看了一位同志的博客,写的是关于他自己去支付宝面试的经历.过程大体是这样的:问答的时候,前面部分,作者都应答如流,说起自己经验如何之丰富,最后面试官问了作者一个问题:请简述多态的概念和作用.结果这 ...

  4. C++多态详解

    多态是面向对象的程序设计的关键技术.多态:调用同一个函数名,可以根据需要但实现不同的功能.多态体现在两个方面,我们以前学过的编译时的多态性(函数重载)和现在我们这一章将要学习的运行时的多态性(虚函数) ...

  5. 【那些年关于java多态应用】

    1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal { public abstract void Say();} 子类: public class ...

  6. JAVA多态

    多态是指当系统A访问系统B的服务时,系统B可以通过多种方式来提供服务,而这一切对系统A是透明的.比如动物园的饲养员能够给各种各样的动物喂食.下图显示了饲养员Feeder,食物Food和动物Animal ...

  7. C#多态“说来也说”——逻辑层BLL中的多态使用

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/p/5861842.html 昨天晚上,有个朋友说学了好久,依然没搞 ...

  8. java多态的理解

    面向对象语言中的类有三个特征,封装.继承.多态.封装与继承很好理解,那什么是多态呢? 1.什么是多态? 多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同 ...

  9. java中如何实现多态

    复习基础知识 多态,就是重载和重写.重载发生在一个类中.重写发生在子类,意思就是子类重写父类相同名称的方法.刚学语言有的东西,不必搞得那么清楚,只有知道怎么用就行了,有的问题你要想真正把它搞得很懂,短 ...

  10. OC多态

    要点: 1.多种形态,引用的多种形态对于一个引用变量,可以指向任何类的对象.对于一个父类的引用(类与类之间有一种继承关系),可以指向子类,也可以指向本类,指向的类型不同.当通过此引用向对象发送消息,调 ...

随机推荐

  1. [Effective Java]第六章 枚举和注解

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  2. C#中Application.DoEvents()的作用

    Visual Studio里的摘要:处理当前在消息队列中的所有 Windows 消息. 交出CPU控制权,让系统可以处理队列中的所有Windows消息,比如在大运算量循环内,加Application. ...

  3. Java I/O 文件加锁,压缩

    文件加锁: 文件加锁机制允许我们同步访问某个作为共享资源的文件. public class Test { public static void main(String[] args) throws I ...

  4. ubuntu 安装遇到黑屏

    1.安装了ubuntu之后,进入登录页面,然后用输入密码后就黑屏了,按ctrl+alt+f1都没用,也进不去命令界面,查找资料后发现是必须在虚拟机->设置->硬件->显示器,上把加速 ...

  5. iOS - MVP 架构模式

    1.MVP 从字面意思来理解,MVP 即 Modal View Presenter(模型 视图 协调器),MVP 实现了 Cocoa 的 MVC 的愿景.MVP 的协调器 Presenter 并没有对 ...

  6. SAP接口编程 之 JCo3.0系列(03) : Table参数

    Table参数作为export parameter BAPI_COMPANYCODE_GETDETAIL是一个适合演示的函数,没有import paramter参数,调用后COMPANYCODE_GE ...

  7. aop前传之代理

    一.jdk提供proxy类对目标对象实现代理,简单的说对方法的调用交给代理对象来操作. 代理目标 代理的具体实现: 代理测试; 简单说:利用proxy生成一个委托类实现代理.这个委托类是目标类的接口的 ...

  8. tomcat PermGen space

    centos: 修改Tomcat中的catalina.sh文件.--用了这个 在catalina.sh文件中,找到cygwin=false,在这一行的前面加入参数,具体如下 # vim TOMCAT_ ...

  9. CodeBlocks使用技巧

    快键键 注释:选中后Shfit + C 取消注释:选中后Shfit + X 查找替换:Ctrl + R Build(Ctrl + F9) Run (Ctrl + F10) Build + Run (F ...

  10. bootstrap学习笔记<三>(文本,代码域,列表)

    文本对齐 .text-left:左对齐 .text-center:居中对齐 .text-right:右对齐 .text-justify:两端对齐 <p class="text-left ...