继承与重写:new与override的内存解析
需积分: 10 97 浏览量
更新于2025-01-01
收藏 39KB DOC 举报
本文将深入探讨C#编程语言中两种重写方法——`override`和`new`的关键概念以及它们在内存机制上的体现。通过分析一个简单的继承实例,我们将揭示实例化过程中父类与子类成员如何分配内存,以及这两种重写关键字如何影响方法的调用。
在C#中,`override`和`virtual`关键字用于实现多态性,允许子类重写父类的虚拟方法。而`new`关键字则用于隐藏父类的同名成员。在内存机制上,`override`和`new`有着明显的区别。
首先,我们来看一下继承实例化的机制。当创建一个子类对象时,会经历以下步骤:
1. **实例化父类成员**:子类实例首先为父类的公有成员分配内存,并初始化这些成员的值。在给出的例子中,父类`Person`有`name`变量和`age`变量(初始值为10),以及一个`public virtual void printA()`虚方法和两个非虚方法`printC()`和`printD()`。
2. **实例化子类成员**:接着,子类`Student`的独有成员被实例化,这包括`num`变量以及`override`重写`printA()`和`new`重写`printD()`的方法。
3. **基类引用**:子类对象中包含一个基类引用,通常在C#中称为`base`,在Java中为`super`。这个引用指向父类部分的内存地址,使得可以通过子类对象访问父类的成员。
当我们创建一个`Student`对象`stu`并将其强制转换为`Person`类型,即`person pe = (person)stu`,`pe`实际上是指向`stu`内的父类部分的引用。这意味着,通过`pe`调用的方法将基于父类的行为,除非这些方法在子类中被重写。
对于`override`关键字,它指示子类方法重写了父类的虚方法。在`Student`类中,`printA()`被`override`重写,因此无论通过`stu`还是`pe`调用`printA()`,都会执行子类的版本,输出"BBBBBBBB"。这是因为虚方法的调用是动态绑定的,它会在运行时根据实际对象的类型决定调用哪个方法。
然而,对于`new`关键字,它不是重写,而是隐藏。在`Student`类中,`printD()`被`new`关键字修饰,这意味着它隐藏了父类的`printD()`方法。如果通过`stu`调用`printD()`,会执行子类的新版本,输出"EEEEEEE"。但当通过`pe`调用`printD()`时,由于`pe`只看到父类的成员,因此会调用父类的`printD()`方法,输出"DDDDDDDD"。这是静态绑定的结果,方法的调用基于变量的声明类型,而非实际对象的类型。
总结来说,`override`和`new`在内存机制上的差异主要体现在方法调用的行为上。`override`实现的是多态,允许子类改变父类虚方法的行为,而`new`则是子类隐藏父类成员的一种方式,提供了另一种方法实现。在实际编程中,选择使用哪种关键字应根据设计需求和预期的行为来决定。
3752 浏览量
109 浏览量
517 浏览量
2023-10-10 上传
630 浏览量
228 浏览量
2020-09-15 上传
150 浏览量
323 浏览量
刘卫黄
- 粉丝: 6
- 资源: 7
最新资源
- netcat-0.7.1.tar.gz
- Noya-Sotabdhi-online-newspaper
- ARC_Alkali_Rydberg_Calculator-2.0.1-cp35-cp35m-win32.whl.zip
- TinDog-Start-master
- github-elements:GitHub的Web组件集合
- 利用百度地图的路书功能实现汽车实时定位
- slate_omen-uitvaartzorg
- snake.html
- tio-udp-showcase-master
- Dday-crx插件
- GdalAlgorithmUtil.zip
- 金色微立体工作总结图表整套下载PPT模板
- dimafeng.github.io:我的技术博客
- svelte-highcharts:苗条的图表
- 快速确保CGridCtrl可见
- OpenGeoAnnotation