全局类与接口 练习

全局类与接口 练习

#practice #global-classes #se24 #alv #badi #abap-objects

📌核心模式 (点击展开)
关键词 答案
Class Builder 事务 SE24,创建和维护全局类
全局类 vs 局部类 全局类存储在 ABAP Repository,所有程序可用
ALV Grid CL_GUI_ALV_GRID,基于控件的面向对象列表
BAdI 基于接口的增强技术,使用 GET BADI / CALL BADI

题目1 - 全局类与局部类的区别 [记忆]

请列出全局类(Global Class)和局部类(Local Class)的至少五个主要区别。

📌查看答案
特征 全局类 局部类
定义位置 ABAP Repository(Class Builder) 程序内部(ABAP 程序源码中)
可见性 所有 ABAP 程序可用 仅在定义它的程序中可见
创建工具 事务 SE24/SE80 在代码编辑器中手动编码
存储 存储在 SAP 系统的类库中 嵌入在具体程序中
命名规范 以 Z/Y 开头(自定义) 任意名称(通常 LCL_ 前缀)
类型池 可使用 Type Groups 不能定义自己的 Type Groups
测试 可创建全局测试类(ABAP Unit) 测试较为受限
继承 可以继承其他全局类 可以继承全局类,但自身不可被全局类继承
传输 通过 CTS 传输 随程序一起传输

题目2 - Class Builder (SE24) 功能 [记忆]

使用事务 SE24 (Class Builder) 创建全局类时,主要有哪些步骤和配置选项?

📌查看答案
创建步骤
  1. 执行事务 SE24,输入类名(如 ZCL_MY_CLASS),点击创建
  2. 填写基本信息:描述(Description)、瞬时性(Instantiation)
  3. 选择类类型(Class、Interface、Exception Class 等)

主要配置选项

  • Properties 标签页:类的基本属性、瞬时性设置(PUBLIC/PROTECTED/PRIVATE/ABSTRACT)
  • Interfaces 标签页:添加实现的全局接口
  • Friends 标签页:声明友元类
  • Attributes 标签页:定义实例和静态属性
  • Methods 标签页:定义方法,可设置参数、异常、方法类型
  • Events 标签页:定义事件
  • Types 标签页:定义公共类型

瞬时性(Instantiation)选项

  • PUBLIC — 任何用户可创建实例
  • PROTECTED — 仅子类可创建
  • PRIVATE — 仅自身可创建(适合单例模式)
  • ABSTRACT — 不能实例化

题目3 - 全局接口的使用 [记忆]

在 ABAP 中如何定义和使用全局接口?全局接口与局部接口在定义和实现上有什么区别?

📌查看答案
定义全局接口
  • 在 SE24 中选择类型为「Interface」,命名以 ZIF_ 开头
  • 在接口中声明方法、属性、事件,但不包含实现

使用全局接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
" 在 SE24 的 Interfaces 标签页中输入接口名
" 或在代码中:
INTERFACE zif_my_interface.
METHODS: calculate
IMPORTING iv_value TYPE i
RETURNING VALUE(rv_result) TYPE i.
ENDINTERFACE.

" 全局类实现接口
CLASS zcl_my_class DEFINITION
PUBLIC CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES zif_my_interface.
ENDCLASS.

区别

  • 全局接口存储在 Repository 中,可被任何全局类或局部类实现
  • 局部接口只能在定义它的程序中使用
  • 全局接口可用于 BAdI 定义和跨组件通信
  • 全局接口的别名(ALIAS)可以在 SE24 中配置

题目4 - ALV Grid Control 基本架构 [记忆]

描述 CL_GUI_ALV_GRID 的基本架构。使用 ALV Grid 显示数据需要哪些关键对象和步骤?

📌查看答案
ALV Grid 架构中的关键对象
  1. 容器对象CL_GUI_CUSTOM_CONTAINER(绑定到屏幕上的 Custom Control)或 CL_GUI_DOCKING_CONTAINER
  2. ALV Grid 对象CL_GUI_ALV_GRID
  3. 字段目录(Field Catalog):类型 LVC_T_FCAT,定义列属性
  4. 布局结构(Layout):类型 LVC_S_LAYO,定义整体显示属性
  5. 数据表:标准内表,存储要显示的数据

基本步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
" 1. 创建容器
DATA(lo_container) = NEW cl_gui_custom_container(
container_name = 'CC_ALV' ).

" 2. 创建 ALV Grid
DATA(lo_grid) = NEW cl_gui_alv_grid(
i_parent = lo_container ).

" 3. 准备字段目录和数据表
" ... (填充 field catalog 和 data table)

" 4. 显示数据
lo_grid->set_table_for_first_display(
CHANGING
it_outtab = lt_data
it_fieldcatalog = lt_fcat ).

需要创建一个带有 Custom Control 的屏幕(Screen),PBO 中初始化 ALV。


题目5 - ALV Grid 事件处理 [记忆]

ALV Grid Control 提供了哪些常用事件?如何注册处理这些事件?

📌查看答案
ALV Grid 常用事件
事件名 触发时机 常见用途
DATA_CHANGED 单元格数据被修改 数据验证
DATA_CHANGED_FINISHED 数据修改完成 更新后处理
DOUBLE_CLICK 用户双击单元格 导航到明细
HOTSPOT_CLICK 点击热点列 链接式导航
TOOLBAR ALV 工具栏初始化 添加自定义按钮
USER_COMMAND 自定义按钮被点击 处理自定义功能
MENU_BUTTON 菜单按钮点击 下拉菜单处理
ONF4 F4 帮助请求 自定义搜索帮助

注册事件处理

1
2
3
4
5
6
7
" 1. 定义处理方法
METHODS on_double_click
FOR EVENT double_click OF cl_gui_alv_grid
IMPORTING e_row e_column.

" 2. 注册处理程序
SET HANDLER lo_handler->on_double_click FOR lo_grid.

注意:对于 DATA_CHANGED 事件,还需调用 lo_grid->register_edit_event( ) 注册编辑事件。


题目6 - BAdI 概念与使用 [记忆]

什么是 BAdI(Business Add-In)?请说明 BAdI 的基本使用流程,包括 GET BADI 和 CALL BADI 的作用。

📌查看答案
BAdI 定义
BAdI(Business Add-In)是 SAP 提供的基于面向对象的增强技术,利用接口实现可插拔的业务逻辑增强。

BAdI 的核心组件

  • BAdI 定义:包含一个全局接口(如 ZIF_BADI_EXAMPLE)
  • BAdI 实现:实现该接口的具体类(如 ZCL_BADI_IMPL)

使用流程

1
2
3
4
5
6
7
8
9
10
11
12
13
" 1. 获取 BAdI 实例(GET BADI)
" 系统根据筛选条件找到匹配的实现类
GET BADI lo_badi
FILTERS
country = 'CN'.

" 2. 调用 BAdI 方法(CALL BADI)
" 系统调用所有活跃实现类的对应方法
CALL BADI lo_badi->calculate_price
EXPORTING
iv_material = lv_matnr
CHANGING
cv_price = lv_price.

关键特点

  • 支持多实现(多个实现类可以同时活跃)
  • 支持筛选条件(Filter)区分不同场景
  • 基于接口,实现完全解耦
  • 使用事务 SE18(定义)和 SE19(实现)管理

题目7 - 全局类设计分析 [分析]

假设你要设计一个全局类 ZCL_ORDER_MANAGER,它需要:1) 支持多种订单类型的处理逻辑;2) 允许客户添加自定义处理逻辑;3) 提供 ALV 显示功能。请分析应该如何组织这个全局类及其相关接口,并说明设计理由。

📌查看答案
推荐设计方案
  1. 核心接口设计

    1
    2
    3
    4
    5
    6
    " 订单处理策略接口
    INTERFACE zif_order_processor PUBLIC.
    METHODS: process_order
    IMPORTING io_order TYPE REF TO zcl_order
    RETURNING VALUE(rv_success) TYPE abap_bool.
    ENDINTERFACE.
  2. 主类设计

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CLASS zcl_order_manager DEFINITION
    PUBLIC CREATE PRIVATE. " 单例或工厂模式
    PUBLIC SECTION.
    INTERFACES: zif_order_processor.
    " 工厂方法
    CLASS-METHODS: get_instance
    RETURNING VALUE(ro_instance) TYPE REF TO zcl_order_manager.
    METHODS: display_orders,
    set_processor.
    PRIVATE SECTION.
    DATA: mo_processor TYPE REF TO zif_order_processor,
    mo_alv_grid TYPE REF TO cl_gui_alv_grid,
    mt_orders TYPE ztt_orders.
    ENDCLASS.

设计理由

  • 接口分离:使用 zif_order_processor 实现策略模式,支持多种订单处理逻辑的灵活切换
  • BAdI 增强:可通过 BAdI 暴露 zif_order_processor,让客户实现自定义逻辑
  • ALV 封装:将 ALV 显示封装在类内部,使用者无需了解 ALV 细节
  • CREATE PRIVATE:配合工厂方法,控制实例化过程
  • 组合优于继承:通过接口注入处理策略,而非通过继承子类化

题目8 - ALV Grid 交互式应用 [应用]

请编写一个完整的 ALV Grid 应用程序的关键代码片段:在屏幕上显示内表数据,双击某行时弹出该行的详细信息。要求使用全局类风格的事件处理。

📌查看答案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
" ---- 数据声明 ----
TYPES: BEGIN OF ty_flight,
carrid TYPE sflight-carrid,
connid TYPE sflight-connid,
fldate TYPE sflight-fldate,
price TYPE sflight-price,
END OF ty_flight.
DATA: gt_flight TYPE STANDARD TABLE OF ty_flight,
go_grid TYPE REF TO cl_gui_alv_grid,
go_cont TYPE REF TO cl_gui_custom_container.

" ---- 事件处理类 ----
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
METHODS on_double_click
FOR EVENT double_click OF cl_gui_alv_grid
IMPORTING e_row e_column es_row_no.
ENDCLASS.

CLASS lcl_event_handler IMPLEMENTATION.
METHOD on_double_click.
DATA: ls_flight TYPE ty_flight.
READ TABLE gt_flight INTO ls_flight INDEX e_row-index.
IF sy-subrc = 0.
MESSAGE s000(oo) WITH '航班:' ls_flight-carrid
'价格:' ls_flight-price.
ENDIF.
ENDMETHOD.
ENDCLASS.

" ---- PBO Module ----
MODULE status_0100 OUTPUT.
IF go_grid IS NOT BOUND.
CREATE OBJECT go_cont
EXPORTING container_name = 'CC_ALV'.
CREATE OBJECT go_grid
EXPORTING i_parent = go_cont.

DATA(lo_handler) = NEW lcl_event_handler( ).
SET HANDLER lo_handler->on_double_click FOR go_grid.

SELECT carrid connid fldate price
FROM sflight INTO TABLE gt_flight
UP TO 50 ROWS.

DATA: lt_fcat TYPE lvc_t_fcat.
" 自动生成字段目录
CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
EXPORTING
i_structure_name = 'SFLIGHT'
CHANGING
ct_fieldcat = lt_fcat.

go_grid->set_table_for_first_display(
CHANGING
it_outtab = gt_flight
it_fieldcatalog = lt_fcat ).
ENDIF.
ENDMODULE.

关键点:事件处理程序必须在 ALV 创建之后注册;e_row-index 用于获取被双击的行号。


📌模式总结 (点击展开)
关键词 答案
全局类 SE24 创建,存储在 Repository,所有程序可用
局部类 程序内定义,仅本程序可见
SE24 标签页 Properties / Interfaces / Friends / Attributes / Methods / Events / Types
瞬时性 PUBLIC / PROTECTED / PRIVATE / ABSTRACT
全局接口 SE24 中 Interface 类型,以 ZIF_ 开头
ALV Grid CL_GUI_ALV_GRID + 容器 + 字段目录 + 布局
ALV 事件 DATA_CHANGED / DOUBLE_CLICK / TOOLBAR / USER_COMMAND
BAdI GET BADI + CALL BADI,基于接口的增强
SE18/SE19 分别用于 BAdI 定义和实现
策略模式 通过接口注入不同实现