【C#】OOP之多态那点事
看上面的UML图,我们创建一个抽象的Instrument类,类中有一个抽象方法paly,然后所有的子类都继承这个类并实现paly方法。(若不懂继承,请参照另一篇:OOP之继承那点事)
我们来看一下类的实现:
public abstract class Instrument
{
public abstract void Play();
} public class Guitor : Instrument
{
public override void Play()
{
Console.WriteLine(string.Format("Play {0}", this.GetType().Name));
}
} public class Paino : Instrument
{
public override void Play()
{
Console.WriteLine(string.Format("Play {0}", this.GetType().Name));
}
} public class Violin : Instrument
{
public override void Play()
{
Console.WriteLine(string.Format("Play {0}", this.GetType().Name));
}
}
在每个子类方法里,我们直接出去字符串。
class Program
{
static void Main(string[] args)
{
Guitor g = new Guitor();
g.Play(); Paino p = new Paino();
p.Play(); Violin v = new Violin();
v.Play(); Console.ReadLine();
}
}
在Main方法里,我们创建了三个对象,然后分别输出。 这个说在我们还没开始多态之前的写法,好麻烦有木有(木有?蹲角落写100个乐器的paly).那什么是多态呢?
什么是多态:一种形态的多种表现形式(好抽象...)
THINK IN JAVA上写到:多态是消除类型之间的耦合关系(还是很抽象)
直接看例子:
class Program
{
static void Main(string[] args)
{
PlayInstrument(new Guitor());
PlayInstrument(new Paino());
PlayInstrument(new Violin()); Console.ReadLine();
} public static void PlayInstrument(Instrument instrument)
{
instrument.Play();
}
}
这样的输出是和上面的例子是一样的,我们改变了什么,我们提供了一个方法,把3个子类的引用放了进去,呀,为什么PlayInstrument的形参是Instrument的对象,这就是多态的关键之处,
我总结了一句话:子类的引用(new Guitor())指向父类的对象(Instrument instrument) ;
static void Main(string[] args)
{
Instrument instrument = new Guitor();
instrument = new Paino();
instrument = new Violin(); Console.ReadLine();
}
这个好神奇有木有,我初学时间也觉得,这个好神奇,这个这么玩的,让我来带领大家进入神秘的多态空间。
向上转型
static void Main(string[] args)
{
Guitor gutior = new Guitor();
Instrument instrument = gutior; Console.ReadLine();
}
向上转型,就说把子类的类型转成父类的,这样是安全的,看上面的例子,如果在VS IDE工具中查看,是没有编译报错的,这时为什么呢?我们来看张图。
这个圆我们把他当作堆(heap)来看,(这没有画栈,因为指向讨论向上转型的安全).我们来看一下Guitor里面包含了Instrument的所有的东西(除了构造,如果说你点不出来私有化的东西,你可以尝试用反射,它的确存在) ,这样我们把大块变成小块是不是很安全呢,因为我大块拥有小块里面所有的东西,所以说向上转型是安全的。
注:相反来说,向下转型是危险的,因为小块变成大块,你不可以控制里面的东西。(协变和逆变概念也差不多,我比较喜欢叫成和谐的变->安全,逆天的变->危险)
这样的话,我们把大块转换成小块(Instrument instrument=new Guitor()),我们只能调用到小块的东西了(所以我们在设计的时候,一般会用接口去限定)
接口其实是应该单独拉出来谈的,但是由于接口基本概念不多,只是在我们OO设计中,接口用处很大,这里属于设计范围,在多态中,用接口做父类和用类写法一样的,可以去试试。
总结一下:
1.向上转型以后,虽然引用还是原本的子类,但是只能用父类的方法了(想想大块变小块)
2.父类方法被子类重写了(virtual,override)以后,向上转型以后,调用相同的方法还是大块的(因为小块的被重写了,这样说感觉很牵强,因为如果我们在子类中用base关键字还是能调用父类的同名方法,至于这块的内存的调用,我一直没找到相关资料,如果有人知道,请分享一下,万分感谢)。
3.接口和抽象类(类)在使用多态的上面是同一个形式
感觉这边写的不好...望大家补充和指出不足,谢谢了。
【C#】OOP之多态那点事的更多相关文章
- 深入理解OOP(三):多态和继承(动态绑定和运行时多态)
在前面的文章中,我们介绍了编译期多态.params关键字.实例化.base关键字等.本节我们来关注另外一种多态:运行时多态, 运行时多态也叫迟绑定. 深入理解OOP(一):多态和继承(初期绑定和编译时 ...
- 深入理解OOP(二):多态和继承(继承)
本文是深入浅出OOP第二篇,主要说说继承的话题. 深入理解OOP(一):多态和继承(初期绑定和编译时多态) 深入理解OOP(二):多态和继承(继承) 深入理解OOP(三):多态和继承(动态绑定和运行时 ...
- 【C#】OOP之继承那点事
前言: 继承这点事,说多不多,说少不少,这里只描述了一些我认为的基础篇,望各位大神指教.本节参照了C#高级编程和Think in java对继承的描述,我个人认为OOP只是思想,故看明白一个就说通的, ...
- OOP & 模块化, 多态, 封装
OOP 面向对象编程 (OOP) 是用抽象方式创建基于现实世界模型的一种编程模式.它使用先前建立的范例,包括模块化,多态和封装几种技术. 在 OOP 中,每个对象能够接收消息,处理数据和发送消息给其他 ...
- PHP基础OOP(二) 多态
PHP 基础 多态 ====================多态是一种思想:从一个基类中派生,响应一个虚命令,产生不同的结果. 不同的对象执行相同的方法而产生不同的行 ...
- 深入理解OOP(四): 多态和继承(抽象类)
在本文中,我们讨论OOP中的热点之一:抽象类.抽象类在各个编程语言中概念是一致的,但是C#稍微有些不一样.本文中我们会通过代码来实现抽象类,并一一进行解析. 深入理解OOP(一):多态和继承(初期绑定 ...
- 深入理解OOP(第一天):多态和继承(初期绑定和编译时多态)
在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现. 无论作为软件设计的高手.或者菜鸟,对于架构设计而言,均需要多次重构.取舍,以有利于整个软件项目的健康构建 ...
- javascript大神修炼记(7)——OOP思想(多态)
读者朋友们大家好,今天我们就接着前面的内容讲,前面我们已经讲到了继承,今天我们就来讲OOP目前最后一个体现,那就是多态,因为javascript语言的灵活性,所以我们是没有办法使用接口的,所以这也给j ...
- C++继承和多态
继承 访问控制 基类的成员函数可以有public.protected.private三种访问属性. 类的继承方式有public.protected.private三种. 公有继承 当类的继承方式为pu ...
随机推荐
- 用户管理 之 用户(User)和用户组(Group)配置文件详解
用户(User)和用户组(Group)的配置文件,是系统管理员最应该了解和掌握的系统基础文件之一,从另一方面来说,了解这些文件也是系统安全管理的重要组成部份:做为一个合格的系统管理员应该对用户和用户组 ...
- MVC的JsonResult用法
在Asp.net Mvc 2中由于对数据的保护,默认情况下request为post,所以在前端请求的时候则需要以post方式request action方法: public JsonResult Ge ...
- 【WebMisCentral WMC】基于Extjs 4.2x的企业级用户授权认证中心系统(SSO+AM+SM),多租户SAAS应用
http://saas.chinacloudtech.com 题记 三年磨一剑,在企业信息化的道路上已经走了3年之久了,3年多时间里做了很多,突破了很多:有无奈和辛酸,也有收货与喜悦:自我价值也在不断 ...
- android 内置视频目录
在做引导界面的时候有一个视频文件, 把它放在res/raw目录下面. 引用方法 如下: videoView = (VideoView) findViewById(R.id.video_view); v ...
- offsetof的使用
#include <stddef.h> #define offsetof ( TYPE, m) (size_t )&reinterpret_cast< const vol ...
- DMSFrame 之SqlCacheDependency(二)
上篇文章介绍的是通知模式的缓存机制,这里介绍的是数据库轮循模式处理,这种模式对SQL2005以下的支持还是比较好的 引擎源码如下: /// <summary> /// 轮循模式 /// 数 ...
- Gson解析数组多类型元素
本文的出现是为了解决以下需求:使用Gson对json数组进行解析,但是数组里面元素的类型是多种的.数据如下: {"list":[{ "type":0, &quo ...
- 基于SWFUpload的angular上传组件
回顾 由于工作内容比较多,特别是架构方面,需要耗费很多的时间调整.重构,因此很久没有写文章了. 话就不多说了,直接进入主题. 实现 首先分析一下SWFUpload初始化的时候,需要传入当前触发上传的元 ...
- 12306外包给阿里巴巴/IBM到底是否可行?
春运开始以后 12306 免不了要罢工几次,毕竟人民群众买票回家的热情实在是高涨,12306 很难承受如此大的压力.每次 12306 网站罢工以后都会有人忍不住对其进行吐槽,而还有人认为如果把 123 ...
- Git--用git建立code库
利用点时间,把自己这段时间使用git的工具的内容,使用过程中遇到的问题都梳理下.首先我们建立一个文件库(基于Ubuntu系统): 1.必须要安装: [html] view plain copy ...