继承多态绕点 C#篇
最近在看博客的时候看到一块很绕的地方,有点类似于以前学习C语言是的i++,++i组合到一起使用的情况,很坑b的,绝对会比i++,++i这种情况更有用,虽然实际代码里面确实很少出现.
面对象像三大特点不是封装,继承和多态吗,绕的地方主要是继承和多态融合到一起的时候.不啰嗦,先看下面代码
public class Shape { }
public class Rectangle : Shape { }
public class Triangle : Shape { }
public class Father
{
public void Foo(Rectangle r)
{
Console.WriteLine("Father Foo(Rectangle)");
}
public virtual void Foo(Triangle t)
{
Console.WriteLine("Father Foo(Triangle)");
}
}
public class Son : Father
{
public void Foo(Shape s)
{
Console.WriteLine("Son Foo(Shape)");
}
public override void Foo(Triangle t)
{
Console.WriteLine("Son override Foo(Triangle)");
}
}
上面三个类是 矩形,三角形 继承 形状,下面两个类是 父亲 有两个方法,一个参数Rectangle的,一个参数Triangle的(这个是虚的),儿子类,一个Shape的方法,一个Triangle的重写方法,这里没有添加一个Rectangle的方法,因为添加了就会覆盖父新的方法.
理论上现在父亲的对象有两个方法,儿子的对象有三个方法,因为有一个Rectangle的方法继承至父亲.那么看下下面代码输出情况
Shape s = new Shape();
Rectangle r = new Rectangle();
Triangle t = new Triangle(); Father fa = new Son();
Son so = new Son(); fa.Foo(r);//
fa.Foo(t); so.Foo(s);//
so.Foo(r);
so.Foo(t);
我们先猜一下//1,//2部分出输什么结果,然后再看一下运行的结果
//
Father Foo(Rectangle)
Son override Foo(Triangle)
//
Son Foo(Shape)
Son Foo(Shape)
Son Foo(Shape)
我们来看一下是否有绕的地方,//1
第1行 fa调Rectangle的方法,那到底应该调用子类的Foo(Shape)还是应该从父类继承的Foo(Rectangle)方法,这里一点绕点,程序运行结果是调的继承的Foo(Rectangle)方法
第2行 fa调Triangle的方法,子类从写了你类的Triangle的方法,标准的多态
//2 这个为什么都是调子类Foo(Shape) 另一个绕点,为什么这次不调从父类继承的Foo(Rectangle)方法,与上面第一条完全矛盾了啊.
先我们来分清一下这几个情况里的多态和继承关系,多态发生的条件是 重写,继承,要有父类引用指向子类,
那么第一组的第1方法调用没有重写,也不是虚方法,所以不是多态,第2个方法调用是多态
第二组的3个方法调用都不是多态.那没有多态的情况下也应该调我继承的方法啊.
所以这里总结下在这种情况下有一个调用的先后顺序
1.有多态的情况下,肯定是在多态系方法里面去调用,哪些是多态系方法呢? 父类的vitual,子类的override就是多态系方法
2.没有多态的情况下调用自己本生(引用类型,不是this指针)的方法(有的情况下),如果没有再调多态系的方法,自己的方法就是我们的普通方法,new覆盖了的方法,和继承来的方法
3.在 自身方法,与继承方法又有个先后顺序,先自身(或new,new也就是自身覆盖),后继承方法.就算你在写代码是 点出来的方法里有继承的,但是自己方法也会先调用
现在再回来看刚才的几个调用绕点的地方
第一组第1个方法调用,因为不是多态,所以看引用本身,有一个Foo(Rectangle)的方法,所以调父类的(就是他本身的)
第二组第2个方法调用,不是多态,先看引用类型(声明时,不是运行时)本身,Son的Foo(Shape s)方法可以调用,所以不会调用继承来的Foo(Rectangle)
第二组第3个方法调用,不是多态,先看引用类型(声时时,不是运行时)本身,Son的Foo(Shape s)可以调用,所以不会考虑继承(这里没有),也不会考虑多态系里的方法(这里有一个)
对以上的理论纯属个人总结,还没有什么依据,只是大家可以共同多写些例子来测试一下,这个可能同语言解释器有关系,因为Java与C++这一点同C#都是互相不同的,后面我再对比一下Java的不同之处.
我也不是用大量的例子来测试的,所以可能存在不准确的地方,请指正,共同进步.
总结一下:
C#里面 重载,继承的情况下方法的访问顺序
1.类型的本身方法
2.继承方法
3.多态系方法
如果是满足多态的情就简单,表现多态就行了。
继承多态绕点 C#篇的更多相关文章
- 继承多态绕点 Java篇
上一篇把C#语言的继承,多态里的特殊的情况做了一下总结,其实那一部分代码都是从Java翻译过去的,今天来总结一下Java在这种情况下是怎么调用的. 上一篇我们说的是:1.多态,只在多态系里方法调用,很 ...
- python面向对象(封装,继承,多态)
python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...
- Python设计模式 - 基础 - 封装 & 继承 & 多态
面向对象的核心是对象,世间万物都可以看作对象,任何一个对象都可以通过一系列属性和行为来描述,可以包含任意数量和类型的数据或操作.类是用来描述具有相同属性和方法的所有对象的集合.类通常是抽象化的概念,而 ...
- Winform打砖块游戏制作step by step第5节---重构代码,利用继承多态
一 引子 为了让更多的编程初学者,轻松愉快地掌握面向对象的思考方法,对象继承和多态的妙用,故推出此系列随笔,还望大家多多支持. 二 本节内容---重构代码,利用继承多态 1. 主界面截图如下: 2. ...
- java面向对象(封装-继承-多态)
框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...
- 浅谈学习C++时用到的【封装继承多态】三个概念
封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...
- No2_4.接口继承多态_Java学习笔记_经典案例
import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import jav ...
- Java继承多态中的方法访问权限控制
java中的方法天生具有继承多态特性,这点与C++有很大不同(需要在父类方发上加virtual关键字),但用起来确实方便了许多. 最简单的继承多态 声明一个接口BaseIF,只包含一个方法声明 pub ...
- Java三大特性(封装,继承,多态)
Java中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的. 一.封装 概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据 ...
随机推荐
- gastic 安装
所有文件下载地址: ftp://ftp.broadinstitute.org/pub/GISTIC2.0/ cd /home/software/ tar zxf GISTIC_2_0_22.tar.g ...
- 关于oracle sql developer乱码的问题
写了一个sql查询,我擦居然乱码了 然后双击下这个框,居然又是中文: 有谁能够告诉我这是什么鬼
- jquery获取当前时间
一.获取当前时间 new Date()方法---------得到结果是当前电脑时间如2011-11-6,10:07 二.获取有个固定的时间方法---------var endtime=new Date ...
- [SAP ABAP开发技术总结]Function远程、同步、异步调用
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- HDU 3496 Watch The Movie(看电影)
HDU 3496 Watch The Movie(看电影) Time Limit: 1000MS Memory Limit: 65536K [Description] [题目描述] New sem ...
- implement "slam_karto" package on a Freight robot
1. login ssh fetch@<robot ip or robot name> 2. set robot master modify .bashrc in robot's com ...
- hdu 5154 Harry and Magical Computer 拓扑排序
Harry and Magical Computer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- 查看perl及其模块
Perl本身自带了很丰富的文档,如果把它们都打印出来,恐怕要耗费大量纸墨.我们试图清点过,但数到2000页左右的时候就数不清了(不用担心,我们用虚拟打印机计算页面数量,这样不会对树木造成威胁,挺环保的 ...
- html 实时监控发送数据
我们都知道ajax可以做异步提交,可以从一个文件里得到返回的数据,如此便能够实时的得到数据,实时刷新页面,如下代码 setInterval(function(){ $.ajax({ url:'demo ...
- flex中实现自动换行
有时候由于label .button等控件中需要用到text属性显示出文本,文本太长就涉及到换行问题,解决方法如下 在actionScript 需要用“ ”实现换行,在需要换行的地方加上它就OK. ...