接口多态

接口多态 (★★★)

#abap-objects #interface #polymorphism #casting

概览表

项目 关键点
接口引用 TYPE REF TO intf 指向实现接口的类实例
Up-cast 对象引用 → 接口引用,隐式安全
Down-cast 接口引用 → 对象引用,显式 ?=
多态调用 通过接口引用统一调用不同实现

接口引用

1
DATA: lo_partner TYPE REF TO lif_partner.  " 接口引用
  • 接口引用只能指向实现了该接口的类的实例
  • 通过接口引用只能访问接口定义的组件
  • 不能访问类的特有组件

Up-cast with Interfaces

1
2
3
4
5
6
7
8
9
10
11
12
DATA: lo_hotel  TYPE REF TO lcl_hotel,
lo_partner TYPE REF TO lif_partner.

CREATE OBJECT lo_hotel.
lo_partner = lo_hotel. " Up-cast: 隐式

" 现在通过 lo_partner 只能访问 lif_partner 的组件:
lo_partner->display_partner( ).
lo_partner->check_availability( iv_date = sy-datum ).

" 以下不行:
" lo_partner->get_hotel_name( ). " 不是接口方法!
💡注意波浪号操作符的省略
使用接口引用时不需要 ~ 操作符:
  • 对象引用: lo_hotel->lif_partner~display_partner( )
  • 接口引用: lo_partner->display_partner( ) ← 更简洁

泛型访问的典型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
" 使用接口引用作为内表行类型
DATA: lt_partners TYPE TABLE OF REF TO lif_partner.

" 收集不同类型的业务伙伴
APPEND NEW lcl_hotel( ) TO lt_partners. " 自动 up-cast
APPEND NEW lcl_rental( ) TO lt_partners. " 自动 up-cast
APPEND NEW lcl_carrier( ) TO lt_partners. " 自动 up-cast

" 统一处理 — 多态!
LOOP AT lt_partners INTO DATA(lo_p).
lo_p->display_partner( ).
lo_p->check_availability( iv_date = sy-datum ).
ENDLOOP.

Down-cast with Interfaces

当需要访问实现类的特有组件时:

1
2
3
4
5
6
7
8
DATA: lo_hotel   TYPE REF TO lcl_hotel,
lo_partner TYPE REF TO lif_partner.

" ... lo_partner 指向某个对象 ...

" Down-cast 回具体类
lo_hotel ?= lo_partner. " 如果实际对象是 lcl_hotel 则成功
lo_hotel->get_hotel_name( ). " 现在可以访问特有方法

接口 vs 继承 — 多态对比

特性 继承多态 接口多态
基础 父类引用 接口引用
引用类型 TYPE REF TO superclass TYPE REF TO interface
可访问组件 父类定义的 接口定义的
Up-cast 子类→父类 对象→接口
典型场景 同一族的对象 提供相同服务的不同类

方法参数使用接口引用

1
2
3
4
5
6
7
CLASS lcl_travel_agency DEFINITION.
PUBLIC SECTION.
METHODS:
add_partner IMPORTING io_partner TYPE REF TO lif_partner.
PRIVATE SECTION.
DATA: mt_partners TYPE TABLE OF REF TO lif_partner.
ENDCLASS.
📌接口引用作为参数
这是面向接口编程的核心:方法不依赖具体类,只依赖接口。
新的实现类只要实现了接口,就可以直接传入。

考试/测试模式

场景/关键词 答案
“接口引用能指向什么” 任何实现了该接口的类的实例
“接口引用能访问什么” 只能访问接口定义的组件
“接口多态的用途” 统一处理实现了相同接口的不同类的对象
“何时需要down-cast” 需要访问实现类特有组件时