
ABAP 接口
一、什么是接口
不同于C++等语言,ABAP语言不支持多重继承。这是因为多重继承使方法调用及类阶 层结构变得复杂。因此,ABAP用接口(Interace)实现从完全没有关系的类中访问其他类。 类、类对象及利用参照变量对个体的访问组成ABAP Obiect的基本概念。下面是接口通过客 户、订单、订单明细的关系创建的典型业务应用软件。
如[图14-15]所示,假设存在存款和提款这两个没有继承关系的相似类,这两个类中都含 有计算相应年度余款的方法,且此方法在两个类中都使用,名字也相同。但具体计算逻辑不 同,因此各自单独在自己类中实现符合的功能。其中余款变量与计算余款的方法使用相同的 名字,因此不必各自单独声明也可通过接口实现。即接口有独立的结构体(数据与方法)。
接口在类的 PUBLICSECTION 中追加自己的组件,因此不能扩展类。接口在继承树中起着两 个不同节点的类互相访问的中介作用。 下面通过比较一般类、抽象类及接口巩固上述内容。
1.比较类与抽象类
一般类可以通过初始化来创建对象(CREATEOBJECT),但是抽象类不可以,只能从 子类继承使用。因为抽象类没有实现功能的IMPLEMENTATION 部分。抽象类是将一些共通 的功能集合在一个类中,然后继承此类在子类中使用。
2.比较类与接口
接口,如抽象类,不能直接通过初始化使用。然而可以追加到类中实现 IMPLEMENTATION。类要实现接口的功能,只能通过接口实现。
3.比较抽象类与接口
抽象类是在子类继承后才能实现自己具备的方法功能,而ABAP对中只能单一继承, 因此继承抽象类的子类不能再继承其他类。但是接口不属于继承,是在类中追加声明的概念 因此可以多重继承。下例是在声明继承抽象类的子类中追加接口的情况。
CALSS CIINHERITITING FROM 抽象类
INTERFACES 接口
ENDCLASS.MOVEf+2(3)TO f2.
二、定义接口
接口如同类,在ABAP程序中也可定义全局 (Global)或局部(Local)接口。定义部 接口如同类 分可以包含属性、方法、事件等所有项目。接口组件不必定义在访问权限领域中,是因为在 类中追加接口时必须定义在PUBLICSECTION 中。另外在类中实现接口的方法,因此接口不 能包含功能实现部分。
INTERFACE intf.
METHODS meth
ENDINTERFACE.MOVE f1+2(3) TO f2.
三、实现接口
接口不同于类,其没有实例,只是定义在类中,并在类的IMPLEMENTATION 中实现接 口的方法。 14.6.2节中定义的接口 intf如下面语句所示,定义在类中。 在类中接口只能定义在
PUBLIC SECTION
中,因此实现接口的方法功能时,接口的组件 会追加到类的 PUBLIC SECTION中。换言之,上语句中接口intf的组件 meth 定义在类的 IMPLEMENTATION
中,则类中会存在intfmeth。如右上图语句所示,接口的方法可以在类 中实现,即接口可以在其他类中实现其功能。
四、参照接口
参照变量可以访问对象。不用创建参照类的参照变量,只需定义参照接口的参照变量就 可以访问对象。即若类中已经实现了接口intf,则只用参照接口的参照变量就可以访问组件, 意味着不必创建类的参照变量。
DATA : irefTYPE REF TO intf.
接口通过 Reference 可以使多个类拥有统一形态。这称为多态性(Polymorphism)。 [例 14-16]是从两个类中实现接口方法的代码。接口在类的 PUBLIC SECTION 中定义。
实现接口的方法利用波浪号(~)。通过图理解[例14-16],在[图14-16]中,定义对象引用变量后通过 CREATE语句创建CREF1、CREF2对象。创建的对象分别指各自的类。即CRFE1 参照的是CLS1,CRFE2参照的是CLS2。尚未生成接口引用变量IRFE,因此只存在对象引 用变量 IRFE。 [例14-16]
REPORT Z14_16.
INTERFACE account.
METHODS calc.
DATA balance TYPE i.
ENDINTERFACE.
CLASS CLS1 DEFINITION.
PUBLIC SECTION.
INTERFACES account.
ENDCLASS.
CLASS CLS1 IMPLEMENTATION.
MMETHOD account~calc.
WRITE : /'Deposit money is : ', account~balance.
ENDMETHOD. "account~calc
ENDCLASS.
CLASS CLS2 DEFINITION.
PUBLIC SECTION.
INTERFACES account.
ENDCLASS.
METHOD account~calc.
WRITE :/"Withdrawl money is : ', account~balance
ENDMETHOD.
"account~calc
ENDCLASS. "CLS2 IMPLEMENTATION
DATA : cref1 TYPE REF TO CLS1.
cref2 TYPE REF TO CLS2.
iref TYPE REF TO account.
START-OF-SELECTION
CREATE OBJECT : crefl, cref2
crefl->account~balance=300.
CALL METHOD: crefl->account~calc.
iref= crefl.
CALL METHOD iref->calc.
cref2->accountbalance = '-200'.
CALL METHOD: cref2->account~calc.
iref= cref2.
CALL METHOD iref->calc.
[结果 14-16]
Deposit money is : 300
Deposit money is : 300
Withdrawl money is : 200-
Withdrawl money is : 200-
在[图14-17]中,定义IREF=CRFE1语句,则CREF1会分配到IREF中。结果对象引用变量IREF 也会指向CCOUNTER1。
五、使用别名
所有接口组件可以利用ALIAS指定其别名(Aliasame)。在接口内再调用其他接口的 Deep组件经常使用。ALIAS只能在接口内或者类的定义部分使用,不能在实现方法功能的 IMPLEMENTATION 中使用。
ALIASES alias FOR inf~coml.
[例 14-17]
REPORT z14_17.
INTERFACE account.
METHODS calc IMPORTING pI TYPE i.
ENDINTERFACE.
"account
CLASS cIs1 DEFINITION,
PUBLIC SECTION.
INTERFACES account.
ALIASES calc FOR
account-calc.
ENDCLASS. "CLS1 DEFINITION
CLASS clsI IMPLEMENTATION.
METHOD account-calc.
WRITE :/'Deposit money is :', pl.
"account~calc
ENDMETHOD.
"CLS1 IMPLEMENTATION
ENDCLASS.
DATA : cref1 TYPE REF TO clsl.
START-OF-SELECTION.
CREATE OBJECT crefl.
[结果 14-17]
Deposit money is : 200
如[例14-7所示,若要在程序中使用接口accoumt的方法calc,则其名字很长,如 account~calc。因此利用ALIAS指定别名为calc,使之变得简单。