深入理解.net - 2.多态 Polymorphsim

通过上篇文章 继承的本质 深入介绍了继承过程中对象的的创建过程,相信对继承已经有了一个深入的理解,本文则详细剖析一下面向对象设计的另一要素多态(Polymorphsim)

什么是多态

官方MSDN上是这样描述的点此可查看原文连接

Polymorphism is a Greek word that means "many-shaped" and it has two distinct aspects:
At run time, objects of a derived class may be treated as objects of a base class in places such as method parameters and collections or arrays. When this occurs, the object's declared type is no longer identical to its run-time type.
Base classes may define and implement virtual methods, and derived classes can override them, which means they provide their own definition and implementation. At run-time, when client code calls the method, the CLR looks up the run-time type of the object, and invokes that override of the virtual method. Thus in your source code you can call a method on a base class, and cause a derived class's version of the method to be executed.

大体意思就是:

  • 在运行时,对象的类型可以和运行时类型不同,派生类在某些地方可以被替换成基类,如方法的参数,集合或者数组。
  • 基类可以定义或实现虚方法,派生类能够重写父类的虚方法,这就意味派生类可以提供他们自己的定义和实现。在运行时,当客户端代码调用这些方法,CLR查找对象的运行时类型,并调用重写的虚方法。因此,你可以使用基类类型调用方法,从而执行派生类的一个实现。ps:翻译的水平一般,大体意思应该写出来了 :)

总结一下就是:

  • 1.派生类(子类)可以以基类(父类)类型出现;
  • 2.在运行时,派生类(子类)以自己的方式来实现;
  • 3.派生类(子类)以基类(父类)的类型使用时,只能使用父类共有或重写的方法,即特有的属性和方法不可以使用;

通俗简单来说就是,声明的时候是基类的类型,而实例化(new)的是派生类,举个栗子

public class Food
{
    private string name = "Food";

    public virtual string GetName()
    {
        return name;
    }
}

public class Bread : Food
{
    private string name="Bread";

    public override string GetName()
    {
        return name;    
    }
}

public class ButterBread : Bread
{
    private string name = "ButterBread";

    public override string GetName()
    {
        return name;
    }
}

Food food = new Bread(); 当我们调用 food.GetName() 时,执行的是 Bread.GetName() 方法,得到的是 "Bread"。如果我们这么写Food food = new ButterBread();,当调用 food.GetName() 时,执行的则是 ButterBread.GetName() 方法,这就是多态,有没有很简单!允许同一个类型具有不同的行为,通过例子是不是比上文扯的一堆要更好理解。

一张图轻松GET多态本质

相信上图很直观的对比了Food food = new Bread();Bread bread = new Bread();之前的区别:二者唯一的不同是在堆栈上维护的Bread实例的地址引用类型不同,food是Food类型的,bread是Bread类型的,但是二者指向的GCHeap上的实例都是Bread类型的实例。简单说明下,TypeHandle(类型句柄)是指向加载该类型的相关元数据信息包括方发表,静态字段等。CLR再第一次加载类型的时候就会创建该类型的方法表,并按继承关系将所有父类的方法copy一份,重写的方法会使用自己的方法覆盖掉。所以多态实际上在运行时执行的还是具体实例化类型的方法表。分享下我一般这么理解:我们吃的是食物,而它是面包。说到底还是要看吃到的是啥。关于详细的LoaderHeap介绍可以参考文末参考链接。

一些思考

面对日渐复杂多变的业务需求,如何使我们的程序更灵活,易扩展,当然是面向抽象编程了,抽象即稳定的,而多态是我们得以实现这一原则的基础。同时掌握了继承多态之后,我们才能更好的学习和理解设计模式。另外发现:看英文的文章比看中文的更容易理解。大家尽量多看些英文的技术文章,不要怕!手边常备个词典就好。

http://www.ymg3874.cn
http://www.jaf1308.cn
http://www.djz1658.cn
http://www.jlh2124.cn
http://www.acj2609.cn
http://www.per1537.cn
http://www.jxa6372.cn
http://www.dja2819.cn
http://www.sml6389.cn
http://www.hgh3722.cn
http://www.ntd5264.cn
http://www.esn7121.cn
http://www.oee2689.cn
http://www.pdh7765.cn
http://www.qsv0141.cn
http://www.mar4014.cn
http://www.rcd9187.cn
http://www.unw3900.cn
http://www.tmo9604.cn
http://www.eko5785.cn
http://www.eqn5017.cn
http://www.oek0353.cn
http://www.hmw0652.cn
http://www.tub1546.cn
http://www.taj7240.cn
http://www.dto7731.cn
http://www.tox1106.cn
http://www.pzx0011.cn
http://www.kdd4058.cn
http://www.bti6873.cn
http://www.nvg6571.cn
http://www.krr6354.cn
http://www.uym8620.cn
http://www.blm3653.cn
http://www.uqt9445.cn
http://www.txr3194.cn
http://www.hqu4552.cn
http://www.veo6686.cn
http://www.usx0758.cn
http://www.bpl6646.cn
http://www.iyi5365.cn
http://www.xgm6868.cn
http://www.hfk7896.cn
http://www.ngp3761.cn
http://www.bwb3762.cn
http://www.jbx0190.cn
http://www.fvj9657.cn
http://www.ife7579.cn
http://www.zws1014.cn
http://www.bou1446.cn
http://www.xvn7640.cn
http://www.zus2206.cn
http://www.muu1638.cn
http://www.sxw8975.cn
http://www.tfu0259.cn
http://www.sfi6595.cn
http://www.jxb0956.cn
http://www.dwk7340.cn

猜你喜欢

转载自blog.csdn.net/shunqixing/article/details/80032727