接口 【interface】
上一篇说到的继承是ABAP OJBECT中应用最广的部分,它是面向对象思想应用的基础.ABAP 对象不能实现多继承,接口则是在继承基础上的延伸,更好的扩充了继承的功能。从而可以使用接口能实现多继承.从而接口是一种独立的结构体,它是类扩展领域.接口能够被不同的类使用。
接口的特性:
INTERFACE my_interface .
METHODS my_interface_method.
ENDINTERFACE.
CLASS interface_class DEFINITION.
PUBLIC SECTION.
INTERFACES my_interface.
ENDCLASS.
CLASS interface_class
IMPLEMENTATION.
METHOD
my_interface~my_interface_method.
DATA: num TYPE I VALUE 10.
Write:/ num.
ENDMETHOD.
ENDCLASS.
a.每个类可以继承多个接口
b.接口扩展类的公有部分(public)
c.类必须在它的实现块(IMPLEMENTATION)中实现接口中的每一个方法.
d.接口方法在类中的实现,采用“INTERFACE ~ METHOD ” 的方式“~”操作符是接口访问它的组件的方式
INTERFACE I1 . METHODS meth. ENDINTERFACE. 接口l1(组件) INTERFACE I2 . METHODS meth. 接口l2(复合) INTERFACES I1. ENDINTERFACE. CLASS interface_class DEFINITION. PUBLIC SECTION. INTERFACES: I2. 引入接口l2 ENDCLASS. CLASS interface_class IMPLEMENTATION. METHOD I1~meth. …. ENDMETHOD. METHOD I2~meth. …. ENDMETHOD. ENDCLASS.
Compound interface
一个新的接口能由其它接口组成,这种接口称作“复合接口.
Component interface
被其它接口包含的接口, 称作“组件接口”.
对于复合接口中没有级别划分,所有接口都是同样的级别.所以不可能出现 l2~l1 的写法.
一个复合接口包括了组件接口仅一次当一个类包含一个复合接口的时候,这个复合接口包含的组件接口也被实现.
INTERFACE I1 . METHODS m1. ENDINTERFACE. INTERFACE I2. METHODS : m2. INTERFACES I1. ALIASES meth1 FOR I1~m1. ENDINTERFACE. CLASS c1 DEFINITION. PUBLIC SECTION. INTERFACES : I2. ALIASES meth2 FOR I2~m2. ENDCLASS. CLASS C1 IMPLEMENTATION. METHOD I1~m1. ... ENDMETHOD. METHOD : I2~m2. ... ENDMETHOD. ENDCLASS.
START-OF-SELECTION. DATA : oref TYPE REF TO c1 CREATE OBJECT oref. CALL METHOD : oref->I2~meth1. CALL METHOD : oref->meth2 .
a.接口的组件全名称能够使用intf~comp语句被添加到其它接口或类中.
b.别名是用来代替接口中组件名称,在类的实现部分,通过别名来代替组件名称.
c.在类或类的对象调用的时候,必须使用接口的组件全名称.
INTERFACE I1. METHODS : m1. ENDINTERFACE. CLASS c1 DEFINITION. PUBLIC SECTION. INTERFACES : I1. ENDCLASS. CLASS C1 IMPLEMENTATION. METHOD I1~m1. ... ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA : oref TYPE REF TO C1, iref TYPE REF TO I1. 接口L1静态引用给引用参数IREF. CREATE OBJECT oref. CALL METHOD : oref->I1~meth1. Iref = oref. 类C1的对象引用给接 口的引用参数IREF CALL METHOD : iref->meth1.
a.类的引用参数是被类的静态类型声明的(oref TYPE REF TO C1).
b.同样接口的引用参数是被接口的静态类型声明的 (iref TYPE REF TO I1).
c.我们能够象类的引用参数一样, 我们能够采用动态类型为接口的引用参数修改它的引类型或者通过对象引用,如 (Iref = oref. or CREATE OBJECT iref TYPE C1.)
d.当接口的引用参数是动态引用或者通过对象引用的时候,它只能访问类中的接口组件实现.
实例:
创建interface:
定义一个方法:
在类 ZCL_VEHICLE_XX中实例化 ZIF_STATUS_XX ,将方法SHOW中的内容 COPY 到 interface中的SHOW方法。然后删除掉原来的SHOW method, 接着为interface 中的show方法创建一个 ALIAS NAME。
在ZCL_VEHICLE_XX中实例化 ZIF_STATUS_XX
METHOD zif_status_xx~show. DATA: id_met TYPE c , speed_met TYPE c , max_speed_met TYPE c . id_met = id . speed_met = speed. max_speed_met = max_speed . DATA msg TYPE string. CONCATENATE 'Vehicle' id_met ', Speed = ' speed_met ', Max-Speed = ' max_speed_met INTO msg. MESSAGE msg TYPE 'I'. ENDMETHOD.
然后DELETE method show , 最后创建一个ALIAS NAME。
激活, Check method ZCL_TRUCK_XX and ZCL_SHIP_XX 。
重新创建一个和ZCL_VEHICLE_XX 这个类没有关联的新类ZCL_HELICOPTER_XX。并且将interface 给到这个新类。
实例化方法 show:
METHOD zif_status_xx~show. DATA msg TYPE string. msg = `Helicopter, idle`. MESSAGE msg TYPE 'I'. ENDMETHOD.
最后,修改 ZCL_APPLICATION_XX 这个类,从而通过start 这个方法输出 新类ZCL_HELICOPTER_XX的内容:
METHOD start. DATA: status TYPE REF TO zif_status_xx, status_tab LIKE TABLE OF status, truck TYPE REF TO zcl_truck_xx, ship TYPE REF TO zcl_ship_xx, heli TYPE REF TO zcl_helicopter_xx. CREATE OBJECT: truck, ship EXPORTING name = 'Titanic', heli. APPEND: truck TO status_tab, ship TO status_tab, heli TO status_tab. truck->speed_up( 30 ). ship->speed_up( 10 ). LOOP AT status_tab INTO status. status->show( ). ENDLOOP. ENDMETHOD.
事件(Event):
事件的工作机制:
在ABAP object 事件中,我们使用发布和预定的机制(publish and subscribe).类声明一个事件,通过实现一个方法来发布这个事件(事件挂在一个方法上,事件一触发就会调用这个方法)一个类可以实现一个方法来预定这个事件.
事件的使用就是3个步骤:
1.在类中定义事件
2.实现句柄方法,把事件与要触发这个事件的类关联起来.
句柄是什么意思,我们可以简单理解它是一个物体的把柄,有了它我们才能抓住这个物体,也就是说没了句柄我们就
没办法把两个对象联系起来.
3.注册事件方法.
1.类及事件的定义: CLASS testing_event DEFINITION. PUBLIC SECTION. EVENTS my_event. METHODS event_raising_method. ENDCLASS. CLASS testing_event IMPLEMENTATION. METHOD event_raising_method. RAISE EVENT my_event. …….. ENDMETHOD. ENDCLASS.
a.事件能声明为一个类或者一个接口的PUBLIC,PROTECTED,PRIVATE的组件.
b.事件能是静态CLASS-EVENTS的,也可以是动态的.
c.事件能被类中的任何方法用RAISE EVENT的方式触发,静态的事件只能被静态的方法触发.
d.事件的参数只限于EXPORTING的类型,用VALUE的形式传递.
e.事件本身是通过方法来实现的,所以事件是没有实现部分的(implementation).
2.类及句柄方法的建立: CLASS test DEFINITION. PUBLIC SECTION. METHODS: event_method FOR EVENT my_event OF testing_event. ENDCLASS. CLASS test IMPLEMENTATION. METHOD event_method. ….. ENDMETHOD. ENDCLASS.
a.任何类都能定义句柄方法为了自身事件或者其它类事件.
b.事件句柄方法使用FOR EVENT (event name) OF {CLASS (class name) | INTERFACE (interface name)} 的附加语句.
c.一个事件能有多个事件句柄与之关联.
3.注册事件: START-OF-SELECTION. DATA: object1 TYPE REF TO test, object2 TYPE REF TO testing_event. CREATE OBJECT: object1, object2. SET HANDLER object1->event_method FOR object2. CALL METHOD : object2-> event_raising_method.
a.当事件被触发的时候,自动的执行事件句柄方法.
b.注册的作用是让对象的句柄方法激发事件.
c.注册过程是动态的,我们使用的语句是SET HANDLER 句柄类的对象-> 句柄方法FOR 定义事件的类对象[ ACTIVATION act ].
d. FOR ALL INSTANCES 是所有对象都能激活句柄的方法.
e.ACTIVATION 是可用的附加段,默认的act值为’X’,如果设定ACT为SPACE,则表示撤消注册事件。
调用EVENT CLASS的事件方法,触发事件然后查看事件的句柄内表,查找它指向的句柄方
法,然后到句柄类中调用句柄的方法.句柄方法是被激发的方法,事件定义类中的事件方法是
触发用的.
例子:
假设 ZCL_SHIP_XX 会触发一个事件,如果速度超过预先设定的最大速度。
在 ZCL_SHIP_XX 定义一个事件DAMAGED。
在方法 SPEED_UP中触发该事件.
重新定义该类的方法 speed_up:
METHOD SPEED_UP. speed = speed + step. IF speed > max_speed. max_speed = 0. CALL METHOD stop. RAISE EVENT damaged. ENDIF. ENDMETHOD.
保存激活。
实现类 ZCL_HELICOPTER_XX handle 类 ZCL_SHIP_XX 中刚才新建的事件。
定义一个方法 RECEIVE 作为句柄 接受 ZCL_SHIP_XX 的 damaged 事件。
实现该句柄。
点选Detail view 按钮:
创建:
给该方法定义一个传入参数:
实例化这个方法:
METHOD receive.
DATA msg TYPE string.
CONCATENATE `Helicopter received call from ` sender->name INTO msg.
MESSAGE msg TYPE ’I’.
ENDMETHOD.
保存激活。
最后,将 ZCL_APPLICATION_XX中的start 方法做修正。
METHOD start. DATA: status TYPE REF TO zif_status_xx, status_tab LIKE TABLE OF status, truck TYPE REF TO zcl_truck_xx, ship TYPE REF TO zcl_ship_xx, heli TYPE REF TO zcl_helicopter_xx. CREATE OBJECT: truck, ship EXPORTING name = 'Titanic', heli. APPEND: truck TO status_tab, ship TO status_tab, heli TO status_tab. SET HANDLER heli->receive FOR ALL INSTANCES. truck->speed_up( 30 ). ship->speed_up( 10 ). LOOP AT status_tab INTO status. status->show( ). ENDLOOP. DO 5 TIMES. ship->speed_up( 10 ). ENDDO. ENDMETHOD.
执行,即可看到效果。