内存探寻2之——从内存的角度,来看继承和多态

在继承和多态中的内存分配机制:

      继承、封装和多态是面向对象的三大支柱要素,也是C#语言中最为重要的概念。在这里无意具体讲解他们的意义、使用方法等,只是想通过具体实例,从它们的内存分配,以期理解其运行机制,从而对继承和多态概念有深层次的理解。

     这里节选Anytao的《你必须知道的.NET》之继承本质论中示例代码演示图片,加以说明:

  public   abstract   class  Animal

    {

        
public   abstract   void  ShowType();

        
public   void  Eat()

        {

            Console.WriteLine(
" Animal always eat. " );

        }

    }

    
public   class  Bird: Animal

    {

        
private   string  type  =   " Bird " ;

        
public   override   void  ShowType()

        {

            Console.WriteLine(
" Type is {0} " , type);

        }

        
private   string  color;

        
public   string  Color

        {

            
get  {  return  color; }

            
set  { color  =  value; }

        }

    }

    
public   class  Chicken : Bird

    {

        
private   string  type  =   " Chicken " ;

        
public   override   void  ShowType()

        {

            Console.WriteLine(
" Type is {0} " , type);

        }

        
public   void  ShowColor()

        {

            Console.WriteLine(
" Color is {0} " , Color);

        }

    }

当运行代码为:

  public   class  TestInheritance

    {

        
public   static   void  Main()

        {

            Bird bird 
=   new  Bird();

            Chicken chicken 
=   new  Chicken();

        }

    }

由我们上文所论述的:自定义对象的内存分配机制,可知,其对应的内存分配图为:

 

从继承的方面:

我们可以得出如下结论:

1.即使是对同名的private类型字段type,当在子类中依然定义时,则在子类对象的字段中依然存在。而父类和其却将type字段都加上了Bird_type和Chicken_type加以区分;

2.Chicken方法表中,可以实现ShowColor方法,其依赖于属性Color。其是可以继承的,因为就其本质,它等价于在C++中的Get和Set函数(这里属性,包含get和set访问器);

 

然而从多态的方面:

  Bird bird2  =   new  Chicken();

然而如果使用这个语句,如果调用bird2.ShowType(),将会产生什么结果呢?

答案是:"Type is Chicken";

这就是多态的魅力!在这里它如何实现的呢?我们详细讲述一下它的实现方法:

1.对于Bird类型引用,他先查阅自己的Method Table 表,检测定位到标记为Virtual的方法或已经是Override的方法,然后从所指向具体的实例的TypeHandler指向的Method Table 中,查阅是否有被标记为override的对应函数,如果有则调用;如果没有,则向上一直追溯至System.Object(例如Object自带的几个方法Tostring()、Equals()等)为止;

2.Override的实现机理就是将子类的同名函数,覆盖掉父类的函数(因为:在初始化Chicken的方法表时是要按父类优先,子类最后的原则的,这样才能够实现"覆盖").然而预期相对应的New关键字(或默认不写时) 。它所做的,就是在子类中另写一个同名方法,用类型来标记(雷同于前述的字段同名情况)。这样同样是用上述调用语句,当父类检测自己的标记为Virtual的方法或已经是Override的方法,然后从所指向具体的实例的TypeHandler指向的Method Table 中,查阅是否有被标记为override的对应函数,如果有,并且,还存在同名的子类型标记的同名函数,则调用标记为本类(父类)的函数,从而没有实现覆盖;如果没有,则向上一直追溯至System.Object(例如Object自带的几个 方法Tostring()、Equals()等)为止;

 

  综述之,实现继承和多态的内存分配机制的差距,以及具体的用Virtual和Override关键字的函数实现覆盖重载 ,让我们看到内存在其中起到的巨大作用,页可以加深对继承和多态——面向对象中最重要的概念的理解,呵呵~

 

 

附:本文代码和演示图片摘自Anytao的《你必须知道的.NET》 一书,特此感谢。。。

 

 

 

 

转载于:https://www.cnblogs.com/yangmingming/archive/2010/02/02/1661794.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值