一个关于继承和多态的问题(思索篇)
在上一篇Blog中给大家留了一个问题,如果大家有上机去尝试一下,就会知道答案是1了。虽然代码用的是Java,但是这个问题是具有同性的,即使换了C#去写,也会让我们思索一番。下面先从Java的角度去阐述一下这个问题。
对于这个答案的解释,我们可以从两个方面去看:一是从语义的角度;首先,g这个方法对于类C而言是继承自类B,那么就应该与类B中的方法g的行为完全一致,而方法g调用了方法f,其访问修饰符是private,也就是说不可以被覆盖(override)了,从这里就可以知道方法g的行为(调用类B中的方法f)就已经确定了。所以类C继承了类B,使用方法g就不能乱来了,就得乖乖的按照类B定义好的方法g办事了;
二是从底层实现的角度;如果大家觉得上面的说法不够说服力的话,还是让我们来点更加细节的吧。我们都知道创建一个实例的时候,会根据继承层次相应地调用不同的构造函数。当类C实例化的时候,先调用类A的构造函数,接着是类B的,最后是类C的,由于我们这里并没有为这三个类定义特殊的构造函数,默认不带参数的构造函数就会被调用了。那么在类C的一个实例被创建的时候,到底发生了什么呢?首先是类A的构造函数被调用,也就是在heap中为这个实例分配了内存以存放实例变量(instance variable)和方法的指针,由于类A中没有实例变量,就只为存放方法g的指针分配了空间,同时这个指针的内容是可以被修改的;接着类B的构造函数被调用,由于方法g被override了,那么原来存放着方法g指针的地址就会被修改,指向类B的方法g,而方法g中调用的方法f由于其访问修饰符是private,所以这个被调用的方法f的指针值就已经固定了;接着类C的构造函数被调用,只是增加了方法f的指针,注意是增加。综上所述,由于在Java中,所有类方法都是虚函数,都是可以被继承的,因此,如果访问修饰符不为private,都会在类构造函数被调用的时候分配空间以初始化这些方法的指针。
以下是上一篇blog中Java代码所对应的C#代码:
namespace DefaultNamespace
{
public class Test {
public static void Main(string[] args) {
A ref1 = new C();
B ref2 = (B)ref1;
Console.WriteLine(ref1.g());
Console.WriteLine(ref2.g());
}
}
public class A {
private int f() {
return 0;
}
public virtual int g() {
return 3;
}
}
public class B: A {
private int f() {
return 1;
}
public override int g() {
return f();
}
}
public class C: B {
public int f() {
return 2;
}
}
}
从以上代码,我们可以发现,C#对于继承体系有着更为严格和具体的定义。譬如需要通过virtual关键字来说明该方法是虚函数,是可以被override的以及override的关键字的使用等。
呼,终于都说完了这一串让自己战战兢兢的文字。还是一句老话,自己明白容易,要讲清楚就难了。关键还是认识不够深刻啊,请各位多多指点了。
转载于:https://www.cnblogs.com/perhaps/archive/2005/01/06/87687.html
一个关于继承和多态的问题(思索篇)相关推荐
- 啥是面向对象?啥是封装、继承、多态?看看这篇文章就够了
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 面向对象 首先我们来扯面向对象吧 面向对象呢也有一个高大上的名字叫OOP,是现在最 ...
- java写一个外网访问的接口_【JAVA基础】一个案例搞懂类、对象、重载、封装、继承、多态、覆盖、抽象和接口概念及区别(中篇)...
0 前言 初学JAVA时,总会对一些概念一知半解,相互混淆,不明其设计的用意,如类.对象.重载.封装.继承.多态.覆盖.抽象类.接口概念.为便于理解和巩固,本文将基于一个案例及其变形,展现各个概念的定 ...
- 一个经典实例理解继承与多态原理与优点(附源码)---面向对象继承和多态性理解得不够深刻的同学请进...
一 引子 都说面向对象的4大支柱是抽象,封装,继承与多态.但是一些初涉编程的开发人员,体会不到继承与多态的妙用,本文就试以一个经典实例来诠释继承与多态的用武之地.本实例的需求来自<重构>一 ...
- 一个关于封装、继承、多态的问题
前两天给一刚毕业的小伙子面试,问java基础学的咋样,答还行,so问了一题蛮经典的问题,结果没答好,小伙伴们可以参考参考 类A public class A { public String s ...
- 【Java设计模式 面向对象设计思想】一 再谈面向对象和封装、抽象、继承、多态四大特性
回看最初的目标:[Java设计模式 学习目标及大纲]高质量代码的标准及实现路径在这篇Blog里我们明确了什么是高质量的代码:易维护.易读.易扩展.灵活.简洁.可复用.可测试,也知道高质量代码的达成路径 ...
- Go 学习笔记(36)— 基于Go方法的面向对象(封装、继承、多态)
Go 面向对象编程的三大特性:封装.继承和多态. 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承:使得子类具有父类的属性和方法或者重新定义.追加属性和方法等 多态:不同对象中同种行为的不 ...
- Python中的继承和多态
本文以生活中的基础现象为切入点,主要介绍了Python基础中继承和多态,包括单继承.多继承的语法.多态常见的 "鸭子类型". 以及如何重写父类的方法都做了详细的讲解. 一.继承的介 ...
- python 继承和多态
python 继承和多态 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Ba ...
- java 封装 继承 堕胎_JAVA封装、继承、多态
封装 1.概念: 将类的某些信息隐藏在类的内部,不允许外部程序访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: a.只能通过规定的方法访问数据 b.隐藏类的实例细节,方便修改和实 ...
- Python面对对象编程——结合面试谈谈封装、继承、多态,相关习题详解
1.面向对象的三大特征 封装:属性和方法放到类内部,通过对象访问属性或者方法,隐藏功能的实现细节.当然还可以设置访问权限; 继承:子类需要复用父类里面的属性或者方法,当然子类还可以提供自己的属性和方法 ...
最新文章
- 【radar】毫米波雷达相关数据集(检测、跟踪、里程计、SLAM、定位、场景识别)总结(1)
- python均线斜率_一根20日均线闯天下?——量化回测“压箱底指标”
- 雷蛇灯光配置文件_雷蛇猎魂光蛛竞技版机械键盘评测
- .net 深入系统编程(三)
- Intellij Idea 离线安装插件
- python线程数组_Python多线程
- cad图框尺寸标准图_基于AutoCAD2020的动态图框制作与图纸比例问题
- 使用authentication进行身份验证,与Forms表单登陆
- ibm服务器硬件故障检测工具,IBM服务器故障提示Memory/bttery problems were detected
- FastReport 安装方法
- How to Write a simple UEFI EDKII Application:如何编写一个UEFI简单的应用程序[5]
- excel数据处理,表格数据处理成树形结构
- 共议新时代的文化自信与守正创新,第十四届文化中国讲坛举办
- 旧电脑很卡怎么重新安装电脑系统?
- java实现报数游戏
- 苹果cms首页文件html,苹果cms首页视频不更新怎么解决
- 使用谷歌学术检索论文小技巧
- html 利用 frameset 进行简单的框架布局
- vim 错误提示解决:The ycmd server SHUT DOWN (restart with ‘:YcmRestartServer‘). Unexpected exit code 1.
- java 实现图片的合成
热门文章
- error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
- Hexo报错Usage: hexo command处理及图片显示问题
- Volley源码解析(二)
- Flink 1.10 SQL、HiveCatalog 与事件时间整合示例
- MediaCodec进行编解码AAC(文件格式转换)
- python基础篇–变量和简单的数据类型(下)
- 画数轴的步骤_上分助手北师大数学七年级上册第二章有理数第二节数轴详细拆解...
- mysql数据库+查询+sequence_MySQL数据库InnoDB存储引擎Log漫游
- 杭电acm1000c语言答案,c语言,杭电acm1328这题怎么做啊,求提示!!!
- html中src中的url,HTML 中的 href\src\url