继承多态绕点 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中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的. 一.封装 概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据 ...
随机推荐
- C#四则运算之策略模式
Calculator.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; ...
- Web开发, 跳转时出现java.lang.ClassNotFoundException
发生这种状况一般都是由于类找不到,要么是web.xml没有配对位置,要么是类没有放好
- CUBRID学习笔记 27 数据类型4
范围比较 数字和字符串比较 字符串被转为double SELECT i FROM t WHERE i <= all {'11','12'}; i ============= 1 2 3 4 字符 ...
- Java中正则Matcher类的matches()、lookAt()和find()的区别<转>
在Matcher类中有matches.lookingAt和find都是匹配目标的方法,但容易混淆,整理它们的区别如下: matches:整个匹配,只有整个字符序列完全匹配成功,才返回True,否则返回 ...
- [转载] MySQL高可用方案选型参考
原文: http://imysql.com/2015/09/14/solutions-of-mysql-ha.shtml?hmsr=toutiao.io&utm_medium=toutiao. ...
- oracle dba 职责, 及个人需要掌握内容
ORACLE DBA 职责, 基本相当于日常工作. 0. 数据库设计 1. 模式对象的创建与管理(table, index 等等) 2. 事物管理, 例如并发等 3. SQL 调优 只是针对SQL的 ...
- select实现输入模糊匹配与选择双重功能
下载jqueryUI插件 引入 <link rel="stylesheet" type="text/css" href="/js/jquery/ ...
- Maven核心概念之依赖,聚合与继承
一.依赖 我们项目中依赖的jar包可以通过依赖的方式(dependencies元素下添加dependency子元素)引入. <dependency> <groupId>juni ...
- Android ViewFlipper控件实例
使用ViewFlipper实现两张图片切换效果,废话不多说,直接上代码. java源码: package com.example.viewflipper; import android.os.Bund ...
- tracert 命令详解
tracert 命令详解 How to Use the TRACERT Utility The TRACERT diagnostic utility determines the route to a ...