类与继承
Source: Dev.to
我们现在通过添加对 类 的支持来完成解释器。
类可以继承自其他类(重新使用它们的属性和方法),同时通过修改和添加实现自定义。

我构建的
Commits bac3f3c, bfa82b9, 03b3af3, 6c70087
我理解的内容
-
类声明
- 解析器为每个类声明创建一个
Stmt.Class节点,节点中包含类名以及它的方法列表。 - 解析器在当前作用域中声明类名,以便类能够在内部引用自身(例如用于递归)。
- 当解释器访问
Stmt.Class时,它会把 AST 节点转换为一个LoxClass对象,该对象保存一个方法映射(每个方法都被转换为LoxFunction)。
- 解析器为每个类声明创建一个
-
类实例 / 对象
- Lox 不使用
new关键字。 LoxClass实现了LoxCallable接口,所以类在被 调用 时会实例化。- 调用类会创建一个新的
LoxInstance并返回它。 - 实例保存对其所属类(
LoxClass)的引用,以便以后能够查找方法。
- Lox 不使用
-
属性
- 字段不在类中声明,而是通过实例的赋值操作创建。
- 当解释器求值得到一个
LoxInstance对象时,它首先调用get(),检查实例的字段映射。 - 如果字段存在,则返回其值;否则解释器会查找方法。如果两者都未找到,则抛出运行时错误。
- 解析器在看到
=符号之前无法区分 set 与 get 表达式。因此它先把左侧解析为普通表达式(get),在遇到=时再把该节点转换为set节点。 - 当调用
set()时,fields映射会被更新(覆盖已有的键)。
-
方法
- Lox 方法没有
fun关键字,并且通过实例访问。 - 如果方法被提取(例如赋值给变量)后再调用,
this必须仍然指向提取该方法的实例。 - 为实现这一点,当访问方法时,
LoxClass会在底层的LoxFunction上调用bind(instance)。 bind()会在方法原始闭包内部创建一个新的环境,在该环境中定义this,并返回一个新的LoxFunction。- 如果在类外部使用
this,解析器(它会跟踪我们是否在类内部)会报告错误;否则它会把this当作普通局部变量来解析。 - 解释器像查找其他变量一样在环境中查找
this,得益于绑定步骤,能够找到正确的实例。
- Lox 方法没有

-
构造函数
- 用户自定义的构造函数叫做
init。 - 当
LoxClass.call发现init方法时,会立即调用它来初始化新实例。 - 调用的参数个数(arity)会与初始化方法的参数数量进行检查。
init总是返回this(即使用户尝试返回其他值)。解析器通过在LoxFunction中跟踪isInitialiser标志来强制这一行为。
- 用户自定义的构造函数叫做
-
继承
- 子类可以通过存储在子类的
LoxClass中的引用继承超类的方法,方法查找会沿着继承链向上搜索。 - 解析器现在会创建一个包含
superclass字段(Expr.Variable)的Stmt.Class节点。 - 解析器检查自继承的情况,如果检测到则报告错误。
- 如果存在超类,解析器会创建一个新作用域并在其中定义
super,使得super对子类的所有方法可用。 - 在创建子类时,解释器会创建一个新环境,将
super指向超类,然后再创建方法。 - 方法查找的顺序是:先检查实例的字段,其次是类的方法,最后是超类的方法(如果有)。如果链的末端为
null,则查找失败。
- 子类可以通过存储在子类的
auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fucafxqk8gaix3iou4h7h.png)
supersuper关键字允许子类覆盖方法,同时仍然能够调用父类的原始实现。- 即使一系列子类都覆盖了同一个方法,
super也始终解析为最近的直接父类实现。
以上全部反映了在添加完整的类支持(包括继承、构造函数和 super 关键字)后,Jlox 解释器的当前状态。
类定义
- 它后面跟着一个点和标识符(
super.method),并被解析为Expr.Super节点。 - 它在超类上查找方法,但将其绑定到当前实例(
this),两者属于不同的环境。 - 解析器将
super视为局部变量,并计算它相对于定义super的环境的距离(跳数)。
接下来:
对 Lox 的一些扩展——对列表和 for‑in 循环的支持。
随想
博客这个项目对我非常有帮助。虽然我目前正在做其他项目,但尝试解释我几个月前所做的事情(!)迫使我回忆细节和背后的理由。某种程度上,我之前获得的洞见仍在影响我当前的工作方式。
我非常喜欢记录我的所作所为,即使是最平凡的活动。在印度哲学中,工作是最高的奉献行为之一。无论我们做什么,只要带着意图去做,就会引导我们走向能力和精通,因为学习和实践的过程帮助我们成为最好的自己。泰戈尔说得好:
“Where tireless striving stretches its arms towards perfection…”
还有哪里能让上帝存在,除了那完美之中?因此,我提醒自己所有学到的东西。
