CLASS lcl_bank_account DEFINITION. PUBLIC SECTION. DATA: balance TYPE p DECIMALS 2. METHODS: deposit IMPORTING iv_amount TYPE p. ENDCLASS.
假设外部代码直接修改 balance 字段。
📌查看答案
封装被违反。
问题分析:
balance 属性被定义在 PUBLIC SECTION 中,这意味着外部代码可以直接读写该属性
外部代码可能绕过 deposit 方法直接修改余额,导致:
无法验证金额的有效性(如负数存款)
无法记录交易日志
数据完整性无法保证
修正方案:
1 2 3 4 5 6 7
CLASS lcl_bank_account DEFINITION. PUBLIC SECTION. METHODS: deposit IMPORTING iv_amount TYPE p, get_balance RETURNING VALUE(rv_balance) TYPE p. PRIVATE SECTION. DATA: balance TYPE p DECIMALS 2. ENDCLASS.
" 创建不同子类对象 DATA: lt_vehicles TYPE TABLE OF REF TO lcl_vehicle. APPEND NEW lcl_car( ) TO lt_vehicles. APPEND NEW lcl_truck( ) TO lt_vehicles. APPEND NEW lcl_bus( ) TO lt_vehicles.
" 统一调用 — 多态! LOOP AT lt_vehicles INTO DATA(lo_v). lo_v->display( ). " 每个对象执行自己的 display 实现 ENDLOOP.
METHODS: set_type IMPORTING !iv_make TYPE string !iv_model TYPE string EXPORTING !ev_result TYPE boolean CHANGING !cv_data TYPE any RETURNING VALUE(rv_count) TYPE i EXCEPTIONS error = 1.
ALIASES alias_name FOR interface_name~method_name.
示例:
1 2 3 4 5 6
CLASS lcl_report DEFINITION. PUBLIC SECTION. INTERFACES lif_printable. ALIASES print FOR lif_printable~print. ALIASES get_page_count FOR lif_printable~get_page_count. ENDCLASS.
DATA: lo_serializable TYPE REF TO lif_serializable.
将实现类的对象赋给接口引用(类似向上转换):
1 2
lo_serializable = NEW lcl_order( ). " lcl_order 实现了 lif_serializable lo_serializable = NEW lcl_product( ). " lcl_product 也实现了 lif_serializable
通过接口引用调用方法:
1
lo_serializable->to_json( ).
实际执行的是具体类(lcl_order 或 lcl_product)的实现版本
优势:
调用者只需要知道接口定义,不需要知道具体的实现类
可以在运行时替换不同的实现,符合”依赖倒置原则”
可以创建接口引用的内表,统一管理不同类型的对象
1 2 3 4 5
DATA: lt_objects TYPE TABLE OF REF TO lif_serializable. " 可以包含 lcl_order、lcl_product 等各种实现类的对象 LOOP AT lt_objects INTO DATA(lo_obj). lo_obj->to_json( ). " 多态调用 ENDLOOP.
INTERFACE lif_saveable. METHODS: save IMPORTING iv_path TYPE string. ENDINTERFACE.
" 类定义 CLASS lcl_document DEFINITION. PUBLIC SECTION. INTERFACES: lif_printable, lif_saveable. ALIASES: print FOR lif_printable~print, save FOR lif_saveable~save. METHODS: constructor IMPORTING iv_title TYPE string. PRIVATE SECTION. DATA: mv_title TYPE string. ENDCLASS.
INTERFACE lif_logger. METHODS: log_info IMPORTING iv_message TYPE string, log_error IMPORTING iv_message TYPE string. ENDINTERFACE.
实现类(示例一个,其余类似):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
CLASS lcl_file_logger DEFINITION. PUBLIC SECTION. INTERFACES lif_logger. ALIASES: log_info FOR lif_logger~log_info, log_error FOR lif_logger~log_error. ENDCLASS.
" 根据配置选择不同的日志记录器 CASE lv_log_type. WHEN 'FILE'. lo_logger = NEW lcl_file_logger( ). WHEN 'DB'. lo_logger = NEW lcl_db_logger( ). WHEN 'EMAIL'. lo_logger = NEW lcl_email_logger( ). ENDCASE.