【转】继承过程中 父类子类的 字段方法 内存分配 (非java语言)

名人名言:思想好比火星:一颗火星会点燃另一颗火星。一个深思熟虑的教师和班主任,总是力求在集体中创造一种共同热爱科学和渴求知识的气氛,使智力兴趣成为一些线索,以其真挚的、复杂的关系——即思想的相互关系把一个个的学生连接在一起。——苏霍姆林斯基 

首先给出部分代码,由此来分析一下运行过程中对象、字段的创建过程,和编译过程中方法列表的创建过程。

public class Animal
{
public virtual void Eat()
{
Console.WriteLine("Animal Eat" );
}

public virtual void Sleep()
{
Console.WriteLine("Animal Sleep" );
}

public void Play()
{
Console.WriteLine("Animal Play" );
}

}

public class Cat : Animal
{
public override void Eat()
{
base.Eat();//调用父类方法
Console.WriteLine("Cat Eat" );
}

public override void Sleep()
{
Console.WriteLine("Cat Sleep" );
base .Sleep();
}

}



 

以上代码 如果在Main方法中 通过 Animal a = new Cat(); 来实现一个父类引用子类对象。

 

这句话首先是创建了一个Animal类型的a的引用,然后 new Cat();创建了一个Cat的对象,最后把这个a这个引用指向了
              new Cat();这个对象的地址。在这个对象创建的过程中其实有很多步骤
             
              首次访问:(在此没有显示的写出类中的构造方法)
                   顺序:子类的静态字段==》子类静态构造==》子类非静态字段==》父类的静态字段==》父类的静态构造==》父类的非静态字段
                             ==》父类的构造函数==》子类的构造函数
                         
              非首次访问:顺序是一样的,只不过少了中间静态字段和构造的过程
              
             这个过程依次类推直到递归到Object结束(在次过程中也是依次给父类分配内存的过程),且字段的在内存中的存储顺序是由上到下排列,object类的字段  排在最前面,
              原因是如果父类和子类出现了同名字段,则在子类对象创建时,编译器会自动认为这是两个不同的字段而加以区别。 
              
              说了对象的创建,其次是方法列表的创建:
              方法列表的创建是在编译时创建的,而对象的创建是在运行时,对象的创建是为了给方法列表一个引用的指针,使其它们动态关联起来。
              方法列表的创建顺序跟字段的的顺序是一样的,也是先父类后子类。(override 和 new 的不同 new主要是会阻断继承树,和隐藏父类方法,创建子类和父类同名的方法)
              父先子后的原因是:在编译时创建方法列表的过程是,先生成父类的方法列表,而后在生成子类的方法列表的时候,会把父类的方法复制一份
              出来,然后拿子类的方法去和父类的比较,如果发现同名的方法,则看子类的方法修饰符是override 还是 new,如果是override 则覆盖父类
              同名的方法(以上所说的父类方法皆是virtual方法,并且这里说的覆盖只是说覆盖方法的实现,而并没有覆盖父类的方法列表,通过base.父类方法名还是可以调用父类的方法),
              如果是new  则在内存中的不同位置创建一个同名的方法。 不同名的,则直接创建。

 

     完成之后,我们可以通过 a这个引用来来调用Cat中的方法。

 

1.思考:如果把上例中Animal的play方法移到Cat中,在Main方法中打算通过a.Paly();来调用子类的Paly方法会发生什么现象? 会编译不通过,为什么呢?

 

按理说子类就是用来扩展父类的,理论上也允许子类有自己的特性啊(方法、字段……)。但问题不是出在子类,而是出在了调用的位置,不能通过a.Play();来调用这个方法,可能大家又不解了,会想 a就是通过 new Cat();这个对象啊出来的,为什么不能调用自己的方法勒,一层层的,最终我们找到原因是在 Animal a 这个申明引用的位置。

 

在此要引入OO 的一个原则: 关注对象原则——调用子类还是父类的方法,取决于创建的对象是子类对象还是父类对象,而不是它的引用类型,而引用指针类型不同的区别决定了不同的对象在方法表中不同的访问权限。

 

由此结合:子类可以调用父类方法和字段,而父类不能调用子类方法和字段  这个概念。就可以知道原因了。

 

在说说OO中的另一个原则:就近原则——对于同名字段或者方法,编译器是按照其顺序查找来引用的,也就是首先访问离它创建最近的字段或者方法。先贴一段代码,然后通过代码来分析。


 View Code 
 

 

class Program
{
static void Main(string [] args)
{
Animal a = new Cat();
// MemberInfo[] m = a.GetType().GetMembers();
// foreach (var item in m)
// {
// Console.WriteLine(item.Name);
// }
// a.Eat();
// a.Play();
//a.Sleep();
Console.WriteLine(a.AnimalName);
}
}

public class Animal
{
public string AnimalName = "Animal" ;
}

public class Cat : Animal
{
public string AnimalName = "Cat" ;
}



 

在代码的Main方法中  Animal a = new Cat();  这个A是Animal 类型的,结合文章开始将的 在编译和运行过程中 子类、父类 的字段和方法以及实例化时候在内存中分配的先后位置可以得出:Animal 类中的 AnimalName 在内存中的位置一定位于 Cat中AnimalName在内存中的位置的前面,根据就近原则打印出的应该是Animal。

 

以上文章大致概括了在继承过程中的 在编译和运行过程中 子类、父类 的字段和方法以及实例化时候在内存中分配 和 执行的先后,以及两个原则,如有错误或者不足的地方请拍砖。后续后更深入的学习oo中的其它内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux设备驱动学习,linux设备驱动学习4

Linux设备驱动程序学习(4)-高级字符驱动程序操作[(1)ioctl and llseek]今天进入《Linux设备驱动程序(第3版)》第六章高级字符驱动程序操作的学习。一、ioctl大部分设备除了读写能力,还可进行超出简单的数据传输之外的操作,所以设备…

几个删除重复记录的SQL语句

几个删除重复记录的SQL语句在大的数据库应用中,经常因为各种原因遇到重复的记录,造成数据的冗余和维护上的不便。1.用rowid方法2.用group by方法3.用distinct方法 1。用rowid方法据据oracle带的rowid属性,进行判断,是否存在重复,语…

【转】产品经理如何进行BRD,MRD,PRD,DRD,FRD编写

转载自:http://minjiechenjava.iteye.com/blog/2304490, 侵删 PRD文档即产品需求文档,也叫业务需求文档。是产品项目由“概念化”阶段进入到“图纸化”阶段的最主要的一个文档。 产品需求文档的作用就是“对MRD中的内容进行指标化和技术化”…

linux磁盘永久挂载教程,linux 永久磁盘挂载

包年包月实例过期后,如果未在规定时间内续费,实例和磁盘均会自动释放,数据永久丢失,无法找回。关于预付费资源过期后的状态变化,请参考 预付费(包年包月)。在使用包年包月实例过程中,如果您觉得当前实例配置…

[代码阅读] ECS toString实现方法

引言 ECS 提供了一种编程方式来生成以不同标记语言编写的文档。它设计为通过面向对象的抽象来生成所有标签。 ECS 目前版本为1.4.2 ,支持 HTML 4.0 和 XML 。 因为工作原因,作者粗略读了ECS的部分原代码,着重了解ECS如果通过toString方法…

【转】设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示

设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示(1.准备工作) 原创 Sean Yu 云计算实战 2019-12-06 本案例适用于开发者入门理解Azure Functions/ IoT Hub / Service Bus / Power BI等几款产品。 主要实战的内容为: 将设备遥…

linux系统管理Linux系统实验,实验三 linux系统管理

实验三 linux系统管理【实验目的】练习Linux系统管理,熟悉Linux系统管理。【实验要求】通过Liunx用户和组管理、设备管理、文件系统管理、进程管理和shell程序设计,能够掌握linux系统管理,完成系统日常维护和管理工作,最后上交实验…

【转】Azure Messaging-ServiceBus Messaging消息队列技术系列1-基本概念和架构

前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家。 首先,Windows Azure提供了两种类型的消息队列机制:Azure Queues和ServiceBus Queues。 其…

Atlas应用程序调试技巧

本文为翻译文章,原文地址:http://atlas.asp.net/docs/Overview/debug.aspx “Atlas”程序由服务器端代码和客户端代码组成,并且,浏览器可能会要去异步请求一些数据。那么,怎样才能Debug这样的web程序呢。本文将告诉…

linux 自动连接无限,hotplug应用实例:自动连接无线网

Linux内核提供了一种机制,使得有热插拔事件(比如插入或拔出U盘)发生时可以执行一个程序,在本文中我称之为hotplug程序。内核在调用hotplug程序时会传递一个命令行参数,这个参数是发生热插拔事件的子系统名称,常见的有usb, module,…

网络数据库的复制和同步(转摘)

数据库复本--网络数据库的复制和同步(1) 数据库复本是复制数据库的技术,利用这种技术,可以是数据库的几个拷贝保持同步。数据库的每个拷贝称为一个复本,并且每个复本都包含一个公共的表、查询、窗体、报表、宏和模块的集合;每个复…

【转】Azure Messaging-ServiceBus Messaging消息队列技术系列2-编程SDK入门

各位,上一篇基本概念和架构中,我们介绍了Window Azure ServiceBus的消息队列技术的概览。接下来,我们进入编程模式和详细功能介绍模式,一点一点把ServiceBus技术研究出来。 本章我们主要介绍ServiceBus的编程SDK编程入门。 首先…

linux octave源码安装,在Linux操作系统上安装Octave的方法

本文介绍在Ubuntu、Debian、Arch Linux、Fedora、OpenSUSE操作系统上安装Octave(也称GNU Octave)的方法,它还支持Flatpak方式安装。简介GNU Octave是一种用于科学和数学计算操作的解释性命令语言,它与Matlab兼容,支持各种扩展,允许…

C#做的一个加密/解密的类

C#做的一个加密/解密的类 大家要有兴趣,可以一起来讨论一下 WebService数据交互安全问题,以下的这个代码,可以用于Dotnet环境下的任何托管方式的应用程序,在实际应用中有两个实例。其中,有一个挂在Internet上的&#x…

【转】理解Azure订阅,账户,活动目录AD,租户等概念

理解Azure订阅,账户,活动目录AD,租户等概念 订阅是啥? 活动目录AD Active Directory啥是租户?订阅是啥? “An Azure subscription is a logical unit of Azure services that links to an Azure account,…

linux安装静默安装was7,WAS7.0 - 安装并升级WAS7.0.0.31(静默安装)

WAS7.0 - 安装并升级WAS7.0.0.31(静默安装)安装之前需要准备的文件:C1G35ML.tar.gz:WAS7.0安装包C1G36ML.tar.gz:WAS升级工具7.0.0-WS-WASSDK-LinuxX64-FP0000031.pak 7.0.0-WS-WAS-LinuxX64-FP0000031.pak :7.0.0.31升级包&…

Vb.Net实现图片合并(相框效果)

Vb.Net实现图片合并(相框效果) Imports System.DrawingImports System.Drawing.ImagingImports System.Drawing.Drawing2D Public Class ImgMerg Public Shared Function MergedImage(ByVal innerImgPath As String, ByVal outerImgPath As String, ByVal mergImgPath As St…

【转】Azure云存储及存储账户概述***

本文介绍下Azure云存储及存储账户。 1、什么是微软Azure云存储 微软Azure云存储是微软提供的云端数据存储服务,是一种可伸缩、持久化的数据存储服务,可以在Internet上被访问并按实际存储容量收费。它也可以被REST API访问,可以保存Azure云端…

插入法排序c语言程序,插入排序算法及C语言实现

插入排序算法是所有排序方法中最简单的一种算法,其主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中,最终得到的序列就是已经排序好的数据。直接插入排序是插入排序算法中的一种,采用的方法是:在添加新的记录时&a…

5分钟能回答的人,年薪25万美金以上

据说,在美国,5分钟能回答这道题的人,平均年薪25万美金以上,题目如下:5个海盗抢到了100颗宝石,每一颗都一样的大小和价值连城。他们决定这么分: 1. 抽签决定自己的号码(1&…