接口定义与实现

接口定义与实现 (★★★)

#abap-objects #interface #alias

概览表

项目 关键点
接口定义 INTERFACE ... ENDINTERFACE. 只有公有组件,无实现
实现接口 INTERFACES intf. 必须在 PUBLIC SECTION 中
接口解析 intf~component 使用波浪号操作符
别名 ALIASES name FOR intf~component.

接口的概念

接口与继承的区别主要在于用途不同:

  • 继承: “是一个”关系 (is-a),共享实现
  • 接口: “提供协议”关系 (protocol),定义服务契约
1
2
3
4
5
从技术角度看:
接口 = 不能实例化的超类 + 无实现 + 只有公有组件

从语义角度看:
接口 = 统一的服务协议,不同类可以不同实现

接口的典型使用场景

场景 说明
统一服务协议 多个类提供相同名称和签名的方法
客户端定义协议 使用者定义需要的服务,提供者实现
模拟多重继承 一个类可以实现多个接口

UML中的接口表示

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──────────────┐          ┌──────────────────────┐
│ «interface» │◄─ - - ──│ LCL_HOTEL │
│ LIF_PARTNER │ implements│ (implements LIF_PARTNER)│
├──────────────┤ └──────────────────────┘
│ +display( ) │
│ +check_avail()│
└──────────────┘

│ uses ( - - →«uses» )
┌──────┴──────┐
│LCL_AGENCY │
│ (uses接口) │
└─────────────┘

定义接口

1
2
3
4
5
6
7
8
INTERFACE lif_partner.
METHODS:
display_partner,
check_availability
IMPORTING !iv_date TYPE d
RETURNING VALUE(rv_avail) TYPE abap_bool.
DATA: mv_name TYPE string.
ENDINTERFACE.
📌接口组件全部是公有的
接口中没有可见性分区(没有 PUBLIC/PROTECTED/PRIVATE)
所有接口组件自动为公有

实现接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CLASS lcl_hotel DEFINITION.
PUBLIC SECTION.
INTERFACES: lif_partner. " 必须在 PUBLIC SECTION
PRIVATE SECTION.
DATA: mv_name TYPE string.
ENDCLASS.

CLASS lcl_hotel IMPLEMENTATION.
METHOD lif_partner~display_partner.
" 实现 display_partner
ENDMETHOD.

METHOD lif_partner~check_availability.
" 实现 check_availability
ENDMETHOD.
ENDCLASS.

实现规则

  1. INTERFACES 语句必须在 PUBLIC SECTION
  2. 接口方法在实现部分中实现
  3. 接口组件使用 intf~component 格式访问

接口解析操作符 (~)

1
2
3
4
5
6
7
8
9
" 在类内部
METHOD some_method.
DATA(name) = lif_partner~mv_name.
lif_partner~display_partner( ).
ENDMETHOD.

" 外部通过对象引用
DATA(lo_hotel) = NEW lcl_hotel( ).
lo_hotel->lif_partner~display_partner( ). " 使用 ~ 访问

别名 (Aliases)

1
2
3
4
5
6
7
CLASS lcl_hotel DEFINITION.
PUBLIC SECTION.
INTERFACES: lif_partner.
ALIASES:
display FOR lif_partner~display_partner,
check FOR lif_partner~check_availability.
ENDCLASS.

使用别名:

1
lo_hotel->display( ).    " 替代 lo_hotel->lif_partner~display_partner( )
💡别名的优势
  • 简化长名称
  • 如果共享组件后来移到接口中,使用别名的代码不需要修改
  • 但别名受类的可见性规则约束

复合接口 (Compound Interfaces)

接口可以继承其他接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
INTERFACE lif_status.
METHODS: get_status RETURNING VALUE(rv_status) TYPE string.
ENDINTERFACE.

INTERFACE lif_serializable.
METHODS: serialize RETURNING VALUE(rv_data) TYPE xstring.
ENDINTERFACE.

" 复合接口
INTERFACE lif_persistent.
INTERFACES: lif_status, lif_serializable.
METHODS: save.
ENDINTERFACE.

考试/测试模式

场景/关键词 答案
“接口有PRIVATE SECTION吗” 没有,所有组件都是公有的
“INTERFACES放在哪里” 必须在 PUBLIC SECTION
“~操作符的含义” 接口解析操作符,intf~component
“别名受什么约束” 受类的可见性规则约束
“接口可以被实例化吗” 不能
“接口和继承的技术区别” 接口无实现部分,所有组件公有