
ABAP 方法
下面观察在 ABAP对象中类的构成要素--方法(Method)的执行。
一、声明方法
声明实例方法如以下语句所示。 声明 Static 方法如下面语句所示。
CLASS-METHODS meth...
声明方法时,可以利用 IMPORTING、EXPORTING、CHANGING、RETURNING定义参数接口。定义接口参数属性,可以选择参数的参照地址(Reference)和值(value)使用。如 Function Module 中通过 EXPORT/IMPORT/CHAINGING.传入/传出数据,在类函数中使用EXPORTINGIIMPORT/CHANGING语句。为了传值到每个参数,需声明VALUE语句。RETURN VALUE 始终返回值。如功能函数执行例外处理时,类也使用EXCEPTIONS。
二、实现方法
在类中声明的方法需在IMPLEMENTATION部分实现其功能(IMPLEMENTATION或者Implement指的是要实现方法的功能)。
METHOD meth.
...
ENDMETHOD
实现方法时不必定义类方法声明部分以外的接口参数。接口参数充当局部变量的角色,因此在方法内可以利用DATA语句定义局部变量。和功能模块相同,可以利用RAISEexception和 MESSAGE RAISING 语句处理错误。使用 Static 方法时要记住,其只适用于类的静态属性
三、调用方法
调用方法时使用如下语句。
CALLMETHOD meth EXPORTING i1=fi2 =f2 ...
IMPORTING el=gle2-g2 ...
CHANGING c1=flc2=f2 ...
RECEIVING r = h
EXCEPTIONS el=rcl e2 =rc2 ...
在方法内调用其他方法时使用如CALL METHOD meth...这样的语句即可。在类外部调用方法时使用CALL METHODref>meth.语句。Ref包含指向类接口值的参照对象变量。调用方法时必须要定义类似EXPORTING或者CHANGING语。但IMPORTING或者RECEIVING 及处理错误的EXCEPTIONS语是可选项,必要时使用即可。调用只带一个IMPORTING 参数的方法时使用下列语句。
CALL METHOD METHOD( f).
带多个IMPORTING 参数的方法使用下列语句。
CALL METHOD METHOD( il =fl i2 =f2 ..).
参数f的值分别分配给变量使用。
参数个数不同时其调用函数的方法请参照[表14-3]。
四、调用动态方法
动态调用方法时使用dynamic符号()。
CALL METHOD ref->(f)
调用 Static 方法如下所示。
- CALL METHOD class=>(f)
- CALL METHOD (c)=>meth
- CALL METHOD(c)=>(f)
与 Function Module 不同,PERFORM 语句可以追加 PARAMETER-TABLE 语句动态定义参数。
CALL METHOD ... PARAMETER-TABLE ptab
EXCEPTION-TABLE etab.
通过[例 14-9]练习动态调用对象方法。 [例14-9]
REPORT z14_09.
CLASS c1 DEFINITION.
PUBLIC SECTION.
DATA : GT_ITAB TYPE TABLE OF sflight,
gs_str TYPE sflight.
METHODS:GET_DATA,
wri_data.
ENDCLASS "C1 DEFINITION
CLASS cI IMPLEMENTATION
METHOD: GET_DATA .
SELECT * INTO TABLE GT_ITAB
FROM sflight
UP TO S ROWS.
ENDMETHOD. "GET_DATA
MMETHOD: wri_data.
LOOP AT GT_ITAB INTO gs_str.
WRITE :/gs_str-carrid, gs_str-connid.
ENDLOOP.
ENDMETHOD. "wri_data
ENDCLASS. "cI IMPLEMENTATION
DATA go_oref TYPE REF TO c1.
DATA gv_mth TYPE string.
FIELD-SYMBOLS <fs> TYPE ANY.
START-OF-SELECTION.
CREATE OBJECT go_oref.
gv_mth='GET_DATA'.
CALL METHOD go_oref->(gv_mth)
[结果 14-9]
AA 0017
AA 0017
AA 0017
AA 0017
AA 0017
可以利用动态()符号动态调用方法。在[例14-91中,调用方法的部分CALLMETHODgv_oref>(gv_meth)和CALLMETHODgo_oref->GET_DATA执行相同的功能。另外,动态属性分配也与调用方法的方法一样。
REPORT z14_10.
CLASS ci DEFINITION
PUBLIC SECTION.
DATA : GT_ITAB TYPE table OF sflight,
gs_str TYPE sflight.
METHODS:GET_DATA.
ENDCLASS. "c1 DEFINITION
CLASS c1 IMPLEMENTATION
METHOD: GET_DATA .
SELECT * INTO TABLE GT_ITAB
FROM sflight
UP TO s ROWS.
ENDMETHOD. "GET_DATA
ENDCLASS. "cI IMPLEMENTATION
DATA go_oref TYPE ref TO c1.
DATA gv_mth TYPE string.
DATA gv_attr TYPE string.
FIELD-SYMBOLS <fs1>type STANDARD TABLE,
FIELD-SYMBOLS <fs2>type ANY.
FIELD-SYMBOLS <fs3> TYPE any.
START-OF-SELECTION.
CREATE OBJECT go_oref.
gv_mth='GET_DATA'.
CALL METHOD go_oref->(gv_mth)
gv_attr ='GT_ITAB'
ASSIGN go_oref->(gv_attr)TO <fs1>.
LOOP AT <fs1> ASSIGNING <f2>.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE <fs2> TO <fs3>.
WRITE : <fs3>.
IF sy-subrc NE 0.
EXIT.
ENDIF.
ENDDO.
WRITE : /.
ENDLOOP.
[结果14-10]
600 AA 00172013-02-09 422.94 USD 747-400 385
600 AA 00172014-03-09 422.94 747-400 USD 385
600 AA 00172013-04-06 422.94 747-400 USD 385
ASSIGN 语句请参照“第10章Field Symbol& Datareference
五、事件处理方法
前面已经提到,事件处理方法(Event Handler Method)是无法用CALL METHOD 调用的特殊类型的方法。该方法不用CALLMETHOD,而是使用事件。为了用事件处理方法定义方法,需在METHODS或者CLASS-METHODS
部分追加如下语句。
METHODS ... FOR EVENT evt OF cif ...
由参数构成的方法称为事件evt的exporting 参数。参数属性由 evt(EVENTS)语句定义。
六、构造雨数
构造函数(Constructor)也是无法用CALLMETHOD调用的特殊函数。然而,当指定类或者新对象的初始值时,在Runtime 环境下会自动被系统调用。该函数有两种类型,分别为实例构造函数和静态构造函数。实例构造函数通过 CREATEOBJECT语句,每次创建接口时都调用;而静态构造函数只在一开始调用类时被调用一次。
METHODS constructor
IMPORTING [VALUE()i1 i2 ..[]] TYPE type [OPTIONAL]...
EXCEPTIONS excl exc2 ...
从以上语句可以看到,构造函数并没有 OUTPUT参数,只是用来定义类的状态。类的实例构造函数用的是已经定义好的方法构造函数。与其他方法一样,在PUBLIC部分声明,在IMPLEMENTATION
部分实现功能。静态构造函数是当刚访问类时在程序中调用一次。类的静态构造函数已经以CLASSCONSTRUCTOR形式在内部定义。与其他方法一样,在PUBLIC部分以CLASS-METHODS CLASS CONSTRUCTOR,形式声明,在IMPLEMENTATION 部分可以实现功能。
CLASS-METHODS CLASS CONSTRUCTOR.
静态构造函数没有参数。因为还没有访问类之前,系统会先调用静态构造函数。因此静态构造函数无法访问自己类中的项目。 下面练习用[例 14-11]明确声明构造函数的方法。
REPORT z14_11.
CLASS c1 DEFINITION.
PUBLIC SECTION.
DATA : gt_itab TYPE TABLE OF sflight,
gs_str TYPE sflight.
DATA :gv_carrid TYPE s_carr_id,
gv_connid TYPE s_conn_id.
METHODS: CONSTRUCTOR IMPORTING i_carrid TYPE s_carr_id
i_connid TYPE s_conn_id.
METHODS:get_data.
ENDCLASS.
CLASS c1 IMPLEMENTATION,
METHOD: CONSTRUCTOR.
gv_carrid=i carrid.
gv_connid =i_connid.
ENDMETHOD.
"c1 DEFINITION
"构造函数
METHOD: get_data.
SELECT * INTO TABLE gt_itab
FROM sflight
WHERE carrid = gv_carrid
AND connid = gv_connid.
ENDMETHOD.
"get_data
ENDCLASS.
"C1 IMPLEMENTATION
DATA go_oref TYPE REF TO c1.
START-OF-SELECTION.
CREATE OBJECT go_oref
EXPORTING
i_carrid = 'AA'.
i_connid= '0017'.
CALL METHOD go_oref->get_data.
LOOP AT go_oref->gt_itab INTO go_oref->gs_str.
WRITE :/go_oref->gs_str-carrid, go_oref->gs_str-connid,
go_oref->gs_str-fldate.
ENDLOOP.
[结果 14-11]
AA 00172012-12-15
AA 0017 2013-01-12
AA 0017 2013-02-09
AA 0017 2014-03-09
[例 14-11]是在定义构造函数方法后创建对象时追加了参数。
CREATE OBJECT go oref
EXPORTING
i_carrid ='AA'
i-connid ='0017'.
在前面也多次提到,构造函数方法是创建对象时自动调用的方法。
CALL METHOD
go_oef->get data.
不必像调用一般方法一样调用构造函数方法。
CALL METHOD
go_oref->CONSTRUCTOR.