事件 练习
事件 练习
#practice #events #oo-events #abap-objects
Related Concepts
📌核心模式 (点击展开)
| 关键词 | 答案 |
|---|---|
| 实例事件定义 | EVENTS evt_name [EXPORTING ...] |
| 静态事件定义 | CLASS-EVENTS evt_name [EXPORTING ...] |
| 触发事件 | RAISE EVENT evt_name |
| 注册处理程序 | SET HANDLER handler->on_event FOR instance |
| SENDER 参数 | 自动传递的发送者引用 |
题目1 - 事件定义关键字 [记忆]
在 ABAP Objects 中,定义实例事件和静态事件分别使用哪两个关键字?
📌查看答案
- 实例事件:使用
EVENTS关键字定义 - 静态事件:使用
CLASS-EVENTS关键字定义
语法示例:
1 | CLASS lcl_example DEFINITION. |
实例事件绑定到具体对象实例,静态事件属于类本身,不依赖实例即可触发和监听。
题目2 - RAISE EVENT 语法 [记忆]
如何在类的方法中触发(raise)一个事件?请写出基本语法,并说明实例事件和静态事件的触发有何区别。
📌查看答案
RAISE EVENT 语句触发事件:1 | RAISE EVENT evt_name |
区别说明:
- 实例事件:在实例方法中使用
RAISE EVENT触发。也可在静态方法中触发同一类的实例事件(但实际不推荐,因为静态方法没有明确的实例上下文)。 - 静态事件:可在实例方法或静态方法中使用
RAISE EVENT触发。
注意:触发事件时,EXPORTING 参数必须与事件定义中的参数匹配。
题目3 - 事件处理程序注册 [记忆]
写出 SET HANDLER 的三种注册形式,并解释每种形式的适用场景。
📌查看答案
为特定实例注册:
1
SET HANDLER handler->on_event FOR obj.
只监听对象
obj触发的事件。为所有实例注册:
1
SET HANDLER handler->on_event FOR ALL INSTANCES.
监听该类所有现有和未来创建的实例触发的事件。
为静态事件注册:
1
SET HANDLER handler->on_event.
不需要指定
FOR,因为静态事件不绑定到实例。
注意:如果不再需要监听,使用 SET HANDLER handler->on_event FOR obj ACTIVATION space. 取消注册。
题目4 - 事件处理方法定义 [记忆]
事件处理方法(handler method)的定义语法是什么?它与普通方法在参数声明上有什么特殊限制?
📌查看答案
FOR EVENT 语法定义:1 | METHODS on_data_changed |
特殊限制:
- 处理方法的参数只能 IMPORTING(不能有 EXPORTING、CHANGING、RETURNING)
- 参数列表必须与事件定义的 EXPORTING 参数匹配
- SENDER 是一个隐式可用的参数,代表触发事件的对象引用,类型为触发事件的类引用
- 即使事件没有定义参数,处理方法仍可声明
IMPORTING sender
题目5 - SENDER 参数的作用 [记忆]
在事件处理方法中,SENDER 参数的作用是什么?它是如何传递的?
📌查看答案
- SENDER 是事件处理方法中的一个隐式可用参数
- 它持有触发事件的对象实例的引用
- 类型为触发事件所在类的对象引用
- 通过 SENDER,处理方法可以访问触发者的公共属性和方法
传递机制:
- SENDER 不需要在事件的
EXPORTING列表中显式声明 - 它由 ABAP 运行时环境自动传递
- 处理方法可以自由选择是否在
IMPORTING中声明使用 SENDER
1 | METHODS on_event |
题目6 - 事件参数传递方向分析 [分析]
为什么事件处理方法(handler method)只能有 IMPORTING 参数,而不能有 EXPORTING 或 RETURNING?请从事件机制的通信模型角度分析原因。
📌查看答案
一对多关系:一个事件可以有多个处理程序(handler)。如果允许处理方法返回值或输出参数,系统无法确定应该将哪个处理程序的返回值传递回触发者。
解耦设计:事件机制的核心是触发者不需要知道谁在监听。如果处理方法能向触发者传回数据,就打破了这种单向通信的解耦。
异步语义:触发者发出事件后继续执行,不等待处理结果。如果需要双向通信,应使用直接方法调用而非事件。
如果确实需要在处理方法中改变数据,可以通过引用传递已有对象(在事件参数中传递对象引用),处理方法修改该对象的状态。
题目7 - 完整事件流程编写 [应用]
请根据以下需求编写完整的 ABAP 代码:
- 类
lcl_timer有一个静态事件timeout,导出参数e_seconds TYPE i - 类
lcl_display有处理方法on_timeout,接收e_seconds并写入WRITE输出 - 在启动程序中注册处理程序并触发事件
📌查看答案
1 | CLASS lcl_timer DEFINITION. |
题目8 - 事件与实例生命周期 [应用]
假设你有一个类 lcl_document,每当文档状态改变时触发事件 status_changed。多个监听者(logger、notifier)需要监听此事件。当文档对象被删除后,注册的处理程序会发生什么?如何安全地管理事件注册的生命周期?
📌查看答案
1 | " 事件定义 |
生命周期管理要点:
垃圾回收机制:当文档对象被删除(没有引用指向它)后,ABAP 垃圾回收器会自动清除与该实例相关的事件注册。
显式取消注册:最佳实践是在不再需要监听时显式取消注册:
1
2SET HANDLER lo_logger->on_status_changed
FOR lo_document ACTIVATION space.内存泄漏风险:如果使用
FOR ALL INSTANCES注册且处理程序对象生命周期很长,可能导致不必要的监听。应确保在适当时机取消注册。安全模式:建议在处理程序类中提供
register( )和unregister( )方法封装 SET HANDLER 逻辑,在 cleanup 方法中统一取消所有注册。
📌模式总结 (点击展开)
| 关键词 | 答案 |
|---|---|
| 实例事件 | EVENTS 关键字定义,绑定到对象实例 |
| 静态事件 | CLASS-EVENTS 关键字定义,属于类级别 |
| 触发事件 | RAISE EVENT evt_name EXPORTING ... |
| 注册-指定实例 | SET HANDLER h FOR obj |
| 注册-所有实例 | SET HANDLER h FOR ALL INSTANCES |
| 注册-静态事件 | SET HANDLER h(无 FOR 子句) |
| 取消注册 | SET HANDLER ... ACTIVATION space |
| 处理方法定义 | FOR EVENT evt OF cls IMPORTING ... |
| 处理方法限制 | 只能有 IMPORTING 参数 |
| SENDER | 隐式传递的触发者对象引用 |
| 一对多模型 | 一个事件可有多个处理程序 |
| 生命周期 | 对象删除后注册自动失效 |