看上面的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之多态那点事的更多相关文章

  1. 深入理解OOP(三):多态和继承(动态绑定和运行时多态)

    在前面的文章中,我们介绍了编译期多态.params关键字.实例化.base关键字等.本节我们来关注另外一种多态:运行时多态, 运行时多态也叫迟绑定. 深入理解OOP(一):多态和继承(初期绑定和编译时 ...

  2. 深入理解OOP(二):多态和继承(继承)

    本文是深入浅出OOP第二篇,主要说说继承的话题. 深入理解OOP(一):多态和继承(初期绑定和编译时多态) 深入理解OOP(二):多态和继承(继承) 深入理解OOP(三):多态和继承(动态绑定和运行时 ...

  3. 【C#】OOP之继承那点事

    前言: 继承这点事,说多不多,说少不少,这里只描述了一些我认为的基础篇,望各位大神指教.本节参照了C#高级编程和Think in java对继承的描述,我个人认为OOP只是思想,故看明白一个就说通的, ...

  4. OOP & 模块化, 多态, 封装

    OOP 面向对象编程 (OOP) 是用抽象方式创建基于现实世界模型的一种编程模式.它使用先前建立的范例,包括模块化,多态和封装几种技术. 在 OOP 中,每个对象能够接收消息,处理数据和发送消息给其他 ...

  5. PHP基础OOP(二) 多态

    PHP 基础  多态  ====================多态是一种思想:从一个基类中派生,响应一个虚命令,产生不同的结果.                不同的对象执行相同的方法而产生不同的行 ...

  6. 深入理解OOP(四): 多态和继承(抽象类)

    在本文中,我们讨论OOP中的热点之一:抽象类.抽象类在各个编程语言中概念是一致的,但是C#稍微有些不一样.本文中我们会通过代码来实现抽象类,并一一进行解析. 深入理解OOP(一):多态和继承(初期绑定 ...

  7. 深入理解OOP(第一天):多态和继承(初期绑定和编译时多态)

    在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现. 无论作为软件设计的高手.或者菜鸟,对于架构设计而言,均需要多次重构.取舍,以有利于整个软件项目的健康构建 ...

  8. javascript大神修炼记(7)——OOP思想(多态)

    读者朋友们大家好,今天我们就接着前面的内容讲,前面我们已经讲到了继承,今天我们就来讲OOP目前最后一个体现,那就是多态,因为javascript语言的灵活性,所以我们是没有办法使用接口的,所以这也给j ...

  9. C++继承和多态

    继承 访问控制 基类的成员函数可以有public.protected.private三种访问属性. 类的继承方式有public.protected.private三种. 公有继承 当类的继承方式为pu ...

随机推荐

  1. 你可能不知道的python

    1.如何循环获得下标,使用 enumerate ints = ['a','b','c','d','e','f'] for idx, val in enumerate(ints): print idx, ...

  2. 聊聊CSS postproccessors

      阿里妈妈 @一丝 准备发布其CSSGrace,即CSS后处理插件,于是顺便聊聊CSS postprocessors. 从Rework说起 Rework是TJ大神开发的CSS预处理框架.但为什么会出 ...

  3. 使用Ant编译提示Class not found: javac1.8

    无论是使用Eclipse还是使用Ant命令,都可能会在编译时遇到提示:Class not found: javac1.8 今天用Ant打包Android,apk,运行出现了batch_build.xm ...

  4. [GraphQL] Use GraphQLNonNull for Required Fields

    While certain fields in a GraphQL Schema can be optional, there are some fields or arguments that ar ...

  5. 前端经常使用插件使用文档 以及demo

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  6. Codeforces Round #197 (Div. 2) (A、B、C、D、E五题合集)

    A. Helpful Maths 题目大意 给一个连加计算式,只包含数字 1.2.3,要求重新排序,使得连加的数字从小到大 做法分析 把所有的数字记录下来,从小到大排序输出即可 参考代码 #inclu ...

  7. APP-BOM-20516 错误处理一例

    昨天在处理一个工单异常时,需要将一个Released的工单改为Unreleased状态,程序报APP-BOM-20516错误,如下图.百度只搜到两条记录,均无用.Google能搜到的多一些,也无用.进 ...

  8. Qt5 从头学(2)--手动构建HelloWold

    在上一篇随笔中已经搭建好了Qt5的的开发环境,并且通过Qt Creator自动构建了一个视窗程序.在这篇文章中我们将手动编写一个HelloWold程序,简单了解一下Qt的构建过程.这里我们不会涉及到Q ...

  9. joomla3.1安装不通过Magic Quotes GPC解决方法

    测试安装下joomla 3.1稳定版,但是不能成功,Magic Quotes GPC始终显示 否红色,这样就安装不了了! 要解决这个很简单,开启Magic Quotes GPC就行了,于是找到php. ...

  10. java中图片文件的判断

    javax.imageio 类 ImageIO BufferedImage bi = ImageIO.read(resFile);//resFile --- InputStream if(bi == ...