编译原理之美
宫文学
北京原点代码 CEO
46197 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
编译原理 · 期中考试周 (1讲)
编译原理之美
15
15
1.0x
00:00/00:00
登录|注册

09 | 面向对象:实现数据和方法的封装

静态成员的生存期
对象成员变量的生存期
对象成员的作用域
类的可见性
扩展语言的类型机制
自定义类声明变量
对象成员的可见性
表达式的求值
点操作符
内存管理方式比较
对象保存在堆里
对象保存在栈里
类的构造方法
缺省初始化方法
通过构造方法创建对象
类的方法
类的成员
类的主体
类声明
生存期的角度
作用域角度
类型角度
一课一思
课程小结
访问对象的属性和方法
如何在内存里管理对象的数据
对象是怎么实例化的
设计类的语法,并解析它
面向对象的语义特征
面向对象:实现数据和方法的封装

该思维导图由 AI 生成,仅供参考

在现代计算机语言中,面向对象是非常重要的特性,似乎常用的语言都支持面向对象特性,比如 Swift、C++、Java……不支持的反倒是异类了。
而它重要的特点就是封装。也就是说,对象可以把数据和对数据的操作封装在一起,构成一个不可分割的整体,尽可能地隐藏内部的细节,只保留一些接口与外部发生联系。 在对象的外部只能通过这些接口与对象进行交互,无需知道对象内部的细节。这样能降低系统的耦合,实现内部机制的隐藏,不用担心对外界的影响。那么它们是怎样实现的呢?
本节课,我将从语义设计和运行时机制的角度剖析面向对象的特性,带你深入理解面向对象的实现机制,让你能在日常编程工作中更好地运用面向对象的特性。比如,在学完这讲之后,你会对对象的作用域和生存期、对象初始化过程等有更清晰的了解。而且你不会因为学习了 Java 或 C++ 的面向对象机制,在学习 JavaScript 和 Ruby 的面向对象机制时觉得别扭,因为它们的本质是一样的。
接下来,我们先简单地聊一下什么是面向对象。

面向对象的语义特征

我的一个朋友,在 10 多年前做过培训师,为了吸引学员的注意力,他在讲“什么是面向对象”时说:“面向对象是世界观,是方法论。”
虽然有点儿语不惊人死不休的意思,但我必须承认,所有的计算机语言都是对世界进行建模的方式,只不过建模的视角不同罢了。面向对象的设计思想,在上世纪 90 年代被推崇,几乎被视为最好的编程模式。实际上,各种不同的编程思想,都会表现为这门语言的语义特征,所以,我就从语义角度,利用类型、作用域、生存期这样的概念带你深入剖析一下面向对象的封装特性,其他特性在后面的课程中再去讨论。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

面向对象编程是现代计算机语言中非常重要的特性,其核心特点之一就是封装。封装允许对象将数据和对数据的操作封装在一起,隐藏内部细节,只提供接口与外部交互,从而降低系统耦合,实现内部机制的隐藏。从语义设计和运行时机制的角度来剖析面向对象的特性,可以更深入理解其实现机制,包括类型、作用域、生存期等概念。通过对类的语法设计和解析,可以更深刻地理解面向对象的原理。在实际动手解析代码中的类时,需要进行词法分析、语法分析和语义分析,以识别和记录类型,进行变量类型的消解,并建立符号表来保存信息。了解了面向对象在语义上的原理之后,可以进一步了解运行期如何执行具有面向对象特征的程序,包括实例化对象、内存管理和访问对象的属性和方法。文章深入剖析了面向对象的实现机制,对读者理解面向对象编程具有重要指导意义。文章还讨论了对象的实例化、内存管理和访问属性方法的相关内容,以及对面向对象的本质特征进行重新解读的重要性。通过对类的语法和语义的剖析和运行机制的落地,读者能够更好地理解面向对象的机制,并更好地使用语言的面向对象特性。文章还提出了思考问题,引导读者思考所熟悉的语言的面向对象机制在底层的实现方式以及在类型、作用域和生存期三个方面的特点。整体而言,本文深入剖析了面向对象编程的实现机制,对读者理解面向对象编程具有重要指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编译原理之美》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(12)

  • 最新
  • 精选
  • mcuking
    这个脚本语言使用 Java 或 C++ 实现的,请问下我想用 javascript 实现一个这样的脚本语言可以吗?

    作者回复: 可以的。当然可以。 如果你用工具的话,antlr是支持javascript的。 如果不用工具,手写词法分析器和语法分析器的话,那就更没有问题了。 我后面可能会抽时间用TypeScript(或其他语言)写一个版本,用于写Visual Studio Code的插件。 再抽出时间,我其实会拿playscript写playscript的编译器,也就是实现自举:-)

    2019-09-08
    2
    13
  • 逸飞兮
    老师,您好,提个小建议。代码可以按照每节课程建一个文件夹,如果后面课程的代码是基于之前的,可以复制一份到对应的文件夹再修改,这样通过目录可以直接看到整个过程。没有一直跟着老师的课程节奏走,看代码需要翻git记录,有些麻烦。

    作者回复: 多谢建议! 目前,我尽量保证已经拷贝到文稿里的代码,就不再有变化。 如果有变化,我就按照你说的版本管理办法,建多个目录! 我抽时间要把代码库优化一下。整理得更整齐一些。

    2019-09-03
    9
  • 沉淀的梦想
    语义分析的时候,有的时候在listener的enter中实现,有的时候在exit中实现,listener的enter和exit方法的具体区别是什么呢?

    作者回复: 计算顺序是语义分析中的一个重要问题。 如果本计算要依赖下级节点先计算完,那么就要在exit方法中。 如果如果只依赖自身,那么在哪个方法都可以。比如,判单">"表达式的返回值类型,那肯定是bool,不依赖其他节点。

    2019-09-03
    6
  • 李梁 | 东大
    请问c++ auto变量能进行对象类型推导,这是怎么实现的呢

    作者回复: 你很善于动脑。 类型推断是第11讲里会讲的内容。 我这里提前说一下:类型推断就是两个计算过程。一个是S属性(综合属性)计算,从下往上推导,比如: auto a = 2; 你从叶子节点2能推导出这整个语句的类型是int。 再做I属性(继承属性)计算,就是从上到下的推导。a是这个表达式的叶子节点,a的类型是可以从整个表达式的类型继承下来。

    2019-09-02
    4
  • D
    c语言也能写成面向对象风格,只要实现了面向对象的范式,就是面向对象模型编程,不知说的对不对,还请宫老师指正。

    作者回复: 同意你的看法。 面向对象首先是一种编程思想。哪怕语言层面没有提供直接的支持,也可以按照面向对象编程的思想来做。具体到C语言,它有结构体,有指针,特别是有能够做任何类型转换的void*指针,具有很大的灵活性,所以是能模拟出面向对象的特性的。 操作系统中的很多东西是用C写的,就有面向对象思想。比如,把很多设备都抽象成文件,按照统一的接口操作。 当然在语言层面上提供支持,会容易一些。

    2019-09-02
    2
    3
  • 沉淀的梦想
    文中多次提到的“消解”的具体含义是什么呢?

    作者回复: 对应英文Resolve,可能有些资料也翻译做“解决”? 本质就是建立其正确的引用关系。

    2019-09-03
    2
  • 宋健
    所以说,如果在主类中定义的对象A,A拥有全局作用域,而A里面的方法以及属性就要看A的类里面定义的作用域是吗?

    作者回复: 对不起,没太看明白你的问题... 但我可以总结一下。在面向对象的语言中,变量的作用域有以下几种: 1.类作用域(Class Scope) 也就是成员变量。它们在整个类中可见。 2.方法作用域(Method Scope) 就是方法中的成员变量。 3.块作用域(Block Scope)和循环作用域 一个块中声明的变量,在块外面无效。循环变量也是如此。 此外,还要考虑变量遮蔽(Variable Shadowing),也就是相同名称的变量,会遮蔽外层的变量。在Java里,本地变量可以遮蔽类成员变量,但块作用域中的变量,不允许遮蔽外层的本地变量。在这方面不同的语言定义会有不同。

    2020-04-03
  • 潜龙勿用
    静态成员跟普通成员的区别,就是作用域和生存期不同,它的作用域是类型的所有对象实例,被所有实例共享。生存期是在任何一个对象实例创建之前就存在,在最后一个对象销毁之前不会消失。 ------------------------------------------ “它的作用域是类型的所有对象实例”,这个描述会不会不太准确呢,静态成员先于所有对象实例存在。当没有对象实例也是可以访问静态成员的。还是引入类对象这个概念比较准确吧?
    2021-06-24
    1
  • 核桃
    这里有个疑惑,怎么知道class关键字就可以作为类或者对象呢?例如我要实现一个关键字为A,作用就和c语言的struct类似,那么这里应该还有一个过程?
    2022-05-12
  • getouo
    请问宫老师,怎么支持数组呢
    2021-12-20
    1
收起评论
显示
设置
留言
12
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部