ABAP学习笔记之——第九章:ABAP对象

news2024/11/18 7:31:04

一、类

        类(Class)可看做是对象的骨骼 (Template) 或者对象的类型。另外,类是抽象化对象的明细表。即可以说是制作对象的设计书。对象属性由描述对象的状态和行为的构成要素Component)决定。

比较结构化程序和面向对象程序

例:

*比较结构化程序 和 面向对象程序
DATA :l_file_table TYPE Filetable,
      l_rc         TYPE i,
      l_user_actio TYPE i,
      file_name    TYPE string.
*结构化程序
CALL FUNCTION 'WS_FILENAME_GET'
  EXPORTING
    def_filename = ' '
    def_path     = 'C:\'
    title        = 'FILE OPEN'
  IMPORTING
    filename     = file_name
    rc           = l_rc.

*面向对象程序
CALL METHOD cl_gui_frontend_services=>file_open_dialog
  EXPORTING
    window_title            = 'File Open'
    default_filename        = space
    file_filter             = '*.xls'
    initial_directory       = 'C:\'
    multiselection          = space
  CHANGING
    file_table              = l_file_table
    rc                      = l_rc
  EXCEPTIONS
    file_open_dialog_failed = 1
    cntl_error              = 2
    error_no_gui            = 3
    OTHERS                  = 5.

类中值的传递:exporting和improting

*类中值的传递
CLASS cl DEFINITION.   "定义类
  PUBLIC SECTION.
    DATA: l_char TYPE char20.
    METHODS : set_data IMPORTING p_imp TYPE char20,  "此处的importing表示入参
      get_data EXPORTING p_exp TYPE char20.          "此处的exporting表示出参
ENDCLASS.

CLASS cl IMPLEMENTATION. "定义类的方法
  METHOD set_data.
    l_char = p_imp.
  ENDMETHOD.

  METHOD get_data.
    p_exp = l_char.
  ENDMETHOD.
ENDCLASS.

DATA: go_cref TYPE REF TO cl,  "引用类
      gv_data TYPE char20.

START-OF-SELECTION.
  CREATE OBJECT go_cref.   "实例化对象
  CALL METHOD go_cref->set_data
    EXPORTING                        " 输入参数 将‘test class method’ 赋值给p_imp   然后执行set_data方法,将p_imp赋值给变量l_char。
      p_imp = 'test class method'.

  CALL METHOD go_cref->get_data
    IMPORTING                       "参数输出 执行get_data方法 将l_char赋值给p_exp  然后p_ezp 赋值给gv_data
      p_exp = gv_data.

  WRITE gv_data.

1、构成要素:

        类中存在两种构成要素。一种是各个类的对象中都存在的,另一种与实例数无关,整个类就存在一个。前者是实例-specific 项目,叫做实例 Component (实例组件)。该项目是参照类创建对象时,内存中存在的项目,每每创建对象时都会被初始化。后者是 Non 实例specific 项目,也叫作静态组件。该项目从遇到创建类的语句 (CREATE OBJECT 语)开始,直到程序结束都存储于内存中,是依赖类存在的项目。Static 属性用 CLASS-DATA 语句声明,Static 方法用 CLASS-METHOD 方法声明。Static 属性和方法是为了制作类组件而声明的,即使不创建对象,若已存在于内存中即可以直接使用。

(1)属性:

        属性(Attribute可以拥有 ABAP 所有数据类型的类内部数据字段。对象状态由属性的内容决定。属性的一种类型是 Reference Variable。Reference Variable 可以创建对象及指定地址。Reference Variable 可在类内部定义,并且使它从类内部访问对象。

(2)方法:

        方法用来定义决定对象行为的类内部执行步骤。方法可以访问类的所有属性,且可通过方法修改对象内容。另外,还提供传入传出参数,便于用户交互。在这方面类似于 FunctionModule。类的 PRIVATE 属性只能通过同一类的方法进行修改。在类声明(DEFINTION)部分,利用 METHOD 语句定义,在IMPLEMNT 部分记载方法的功能。

(3)事件:

        事件是没有继承关系的类之间可以相互调用彼此方法的特殊方法。对象(或者类)为了调用其他对象(或者类的事件控制方法时需要使用事件(事件控制方法也是一种方法。)

(4)访问权限区域:

        (1) PUBLIC SECTION

在PUBLIC SECTION 访问权限下定义项目,则在所有类中都可以访问。PUBLIC 类的组件(=成员,项目) 构成类与用户之间的接口。

        (2) PROTECTED SECTION

在 PROTECTED 访问权限下定义的项目,只有自己和继承类才能访问,且充当继承类之间的接口。

        (3) PRIVATE SECTION

在 PRIVATE 访问权限下定义的项目,只显示在相同类的方法中。在外部区域中无法访问,封装在内部类中。IMPLEMENTATION 部分的所有方法在类中都可以访问,没有任何限制。

例1:

*利用类定义继承关系了解访问修饰符
CLASS c1 DEFINITION.
  PROTECTED SECTION.   "若此处是private访问修饰符,将不能被c2继承。会报错
    DATA: l_num TYPE i.
ENDCLASS.

CLASS c2 DEFINITION INHERITING FROM c1. "c2继承c1
  PUBLIC SECTION.
    METHODS :set_data IMPORTING p_imp TYPE i,
      get_data EXPORTING p_exp TYPE i.
ENDCLASS.

CLASS c2 IMPLEMENTATION.
  METHOD set_data.
    l_num = p_imp.
  ENDMETHOD.
  METHOD get_data.
    p_exp = l_num + 1.
  ENDMETHOD.
ENDCLASS.

DATA:go_cref TYPE REF TO c2.
DATA:gv_data TYPE i.

START-OF-SELECTION.
  CREATE OBJECT go_cref.

  CALL METHOD go_cref->set_data
    EXPORTING
      p_imp = '10'.

  CALL METHOD go_cref->get_data
    IMPORTING
      p_exp = gv_data.

  WRITE: / gv_data.

*访问权限示例
CLASS cl DEFINITION.
  PUBLIC SECTION.
    METHODS: set_data IMPORTING p_imp TYPE i,
      get_data EXPORTING p_exp TYPE i.
*  PROTECTED SECTION.   "删掉注释会报错
    DATA: l_num TYPE i.
ENDCLASS.

CLASS cl IMPLEMENTATION.
  METHOD set_data.
    l_num = p_imp.
  ENDMETHOD.
  METHOD get_data.
    p_exp = l_num + 1.
  ENDMETHOD.
ENDCLASS.

DATA: go_cref TYPE REF TO cl.
DATA:gv_data TYPE i.

START-OF-SELECTION.
  CREATE OBJECT go_cref.

  CALL METHOD go_cref->set_data
    EXPORTING
      p_imp = '10'.
  WRITE: 'set_data method:',go_cref->l_num.

  CALL METHOD go_cref->get_data
    IMPORTING
      p_exp = gv_data.
  WRITE: / 'get_data meth

二、对象

  1. 参照对象:

        参照对象变量可以参照或初始化已经存在的对象。指向对象的参照变量清楚对象的实体,类的实例可以利用指向对象的参照变量指定地址。利用参照对象变量的对象不能直接使用对象的构成要素,需利用 Reference (对象地址)。ABAP 中已经存在类似于结构体或者内表中使用的数据类型,也已经定义了参照变量中使用的数据类型。分别是 Class Reference 和Interface Reference。

例:

*分配参照对象
CLASS cls DEFINITION INHERITING FROM object.
  PUBLIC SECTION.
    METHODS:create.
ENDCLASS.

CLASS cls IMPLEMENTATION.
  METHOD create.
    WRITE: / 'object created'.
  ENDMETHOD.
ENDCLASS.

DATA: go_cref1 TYPE REF TO cls.
DATA: go_cref2 TYPE REF TO cls.

START-OF-SELECTION.
  CREATE OBJECT go_cref1.
  go_cref2 = go_cref1.  "等价于 move go_cref1 to go_cref2

  CALL METHOD:go_cref2->create.

2、创建对象:

        利用此参照变量创建类的实例-对象。若参照对象变量在程序声明部分已经参照了对象,创建实例即对象时不用重复使用 TYPE语句。

例:

*创建一个简单的ABAP面向对象程序
CLASS cl DEFINITION.
  PUBLIC SECTION.
    METHODS meth.
ENDCLASS.

CLASS cl IMPLEMENTATION.
  METHOD meth.
    WRITE / 'CALSS TEST'.
  ENDMETHOD.
ENDCLASS.

DATA : go_cref TYPE REF TO cl.

START-OF-SELECTION.
  CREATE OBJECT go_cref.
  CALL METHOD go_cref->meth.

3、访问对象组件:

        为了访问对象的属性和方法,使用 ref->attr 或者 CALL METHOD ref->meth 语句。ref->meth 语句是 CALL METHOD refmeth语句的缩写

4、在类中创建多个实例

(1)分配参照对象

        可以通过 MOVE 语句为其他参照对象分配值。连接在同一个个体的参照变量之间可以创建引用。使用 MOVE 语句或分配符号“=”时系统会自动检查是否为可以分配的类型。

(2)CASTING:

可以利用 casting 符号“?”参照从其他类衍生的对象创建新对象。此时,其他类指的是父类和从父类继承的子类。子类可重新定义,或追加父类的属性及方法。从父类衍生的对象和子类衍生的对象类型可能不同,但此时可用 casting 符号“?”正常执行程序。

例:

*casting 用法
CLASS vehicle DEFINITION INHERITING FROM object.
  PUBLIC SECTION.
    METHODS: create,drive.
  PROTECTED SECTION.
    DATA speed TYPE i VALUE '100'.
ENDCLASS.

CLASS plane DEFINITION INHERITING FROM vehicle.
  PUBLIC SECTION.
    METHODS: fly.
ENDCLASS.

CLASS vehicle IMPLEMENTATION.
  METHOD create.
    WRITE / 'created method.'.
  ENDMETHOD.

  METHOD drive.
    speed = speed + 100.
    WRITE : 'drive is possible,','current speed:',speed.
  ENDMETHOD.
ENDCLASS.

CLASS plane IMPLEMENTATION.
  METHOD fly.
    speed = speed + 1000.
  ENDMETHOD.
ENDCLASS.

DATA:car TYPE REF TO vehicle,
     air TYPE REF TO vehicle.

START-OF-SELECTION.
  CREATE OBJECT car.
  air ?= car.             " 参照父类或从父类继承的子类对象,创建新的对象
  CALL METHOD air->drive.
  CALL METHOD air->create.
*  CALL METHOD air->fly.       “报错,无法调用fly方法

三、方法

1、声明方法:

2、实现方法:

        在类中声明的方法需在IMPLEMENTATION 部分实现其功能 (IMPLEMENTATION 或

者Implement 指的是要实现方法的功能)。

        实现方法时不必定义类方法声明部分以外的接口参数。接口参数充当局部变量的角色,因此在方法内可以利用DATA语句定义局部变量。和功能模块相同,可以利用RAISE exception和MESSAGE RAISING 语句处理错误。使用 Static 方法时要记住,其只适用于类的静态属性。

3、调用方法:

        在方法内调用其他方法时使用如 CALL METHOD meth.这样的语句即可。在类外部调用方法时使用 CALL METHOD ref>meth 语句。Ref包含指向类接口值的参照对象变量。调用方法时必须要定义类似 EXPORTING 或者 CHANGING 语句。但 IMPORTING 或者RECEIVING 及处理错误的 EXCEPTIONS 语句是可选项,必要时使用即可。

 4、调用动态方法:

例:

*动态调用对象方法
CLASS c1 DEFINITION.
  PUBLIC SECTION.
    DATA: gt_itab TYPE TABLE OF sflight,
          gs_str  TYPE sflight.
    METHODS:get_data,wri_data.
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD:get_data.
    SELECT * INTO TABLE gt_itab FROM sflight
      UP TO 5 ROWS.
  ENDMETHOD.

  METHOD:wri_data.
    LOOP AT gt_itab INTO gs_str.
      WRITE: / gs_str-carrid,gs_str-connid.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

DATA go_ref TYPE REF TO c1.
DATA gv_mth TYPE string.

FIELD-SYMBOLS <fs> TYPE any.

START-OF-SELECTION.
  CREATE OBJECT go_ref.
  gv_mth = 'GET_DATA'.
  CALL METHOD go_ref->(gv_mth).
  gv_mth = 'WRI_DATA'.
  CALL METHOD go_ref->(gv_mth).

动态分配属性:

*动态属性分配
CLASS c1 DEFINITION.
  PUBLIC SECTION.
    DATA : gt_itab TYPE TABLE OF sflight,
           gs_str  TYPE sflight.
    METHODS: get_data.
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD:get_data.
    SELECT * INTO TABLE gt_itab
      FROM sflight UP TO 5 ROWS.
  ENDMETHOD.
ENDCLASS.

DATA go_ref 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_ref.
  gv_mth = 'GET_DATA'.
  CALL METHOD go_ref->(gv_mth).

  gv_attr = 'GT_ITAB'.
  ASSIGN go_ref->(gv_attr) TO <fs1>.   "fs1  指向 c1 类的gt_itab属性

  LOOP AT <fs1> ASSIGNING <fs2>.
    DO.
      ASSIGN COMPONENT sy-index OF STRUCTURE <fs2> to <fs3>.  "通过字段号分配
      WRITE: <fs3>.
      IF sy-subrc NE 0.
        EXIT.
      ENDIF.
    ENDDO.
    WRITE : / .
  ENDLOOP.

5、事件处理方法:

        事件处理方法 (Event Handler Method)是无法用 CALL METHOD 调用的特殊类型的方法。 该方法不用 CALL METHOD,而是使用事件。为了用事件处理方法定义方法,需在 METHODS 或者 CLASS-METHODS 部分追加如下语句。

6、构造函数:

        构造函数(Constructor)也是无法用 CALL METHOD 调用的特殊函数。然而,当指定或者新对象的初始值时,在 Runtime 环境下会自动被系统调用。该函数有两种类型,分别实例构造函数和静态构造函数。实例构造函数通过 CREATE OBJECT 语句,每次创建接口都调用;而静态构造函数只在一开始调用类时被调用一次。

例:

*构造函数
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.

  METHOD:get_data.
    SELECT * INTO TABLE gt_itab
      FROM sflight
      WHERE carrid = gv_carrid
      AND connid = gv_connid.
  ENDMETHOD.
ENDCLASS.

DATA:go_ref TYPE REF TO c1.

START-OF-SELECTION.
  CREATE OBJECT go_ref    "构造方法。创建对象的时候自动调用
    EXPORTING
      i_carrid = 'AZ'
      i_connid = '0555'.

  CALL METHOD go_ref->get_data.

  LOOP AT go_ref->gt_itab INTO go_ref->gs_str.
    WRITE : / go_ref->gs_str-carrid, go_ref->gs_str-connid,go_ref->gs_str-fldate.
  ENDLOOP.

四、继承

        继承(Inheritance)是使类之间拥有共同的属性及方法的功能。一个类通过分析过程衍生为更详细且精制的子类,此时子类会继承父类的属性及方法。使用继承的根本原因在于类的重复利用。

        在子类中不用附加声明属性和方法。但是子类可以访问超级类的 PUBLIC、PROTECTED组件。子类中虽然存在超级类的 PRIVATE 组件,但也需要以相同的名字再次定义。从超级类继承的子类方法可以访问超级类的 PRIVATE 属性。

1、重新定义方法

        连接在子类中的所有参照变量可使用重新定义的方法。即使 Reference 参照超级类也会调用重新定义的方法。在重新定义的方法内,可以使用 super-> 语句访问原有的超级类中的方法。这样可以使子类免去重复编码直接使用超级类的方法。

例:

*重定义方法、调用父类原有的method
CLASS c1 DEFINITION INHERITING FROM object.
  PUBLIC SECTION.
    METHODS:create.
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD create.
    WRITE: / 'Original method is called'.
  ENDMETHOD.
ENDCLASS.

CLASS c2 DEFINITION INHERITING FROM c1.
  PUBLIC SECTION.
    METHODS:create REDEFINITION.      "重定义create方法
ENDCLASS.

CLASS c2 IMPLEMENTATION.
  METHOD create.
    CALL METHOD super->create.       "调用父类的create方法
    WRITE: / 'methid is redefined'.
  ENDMETHOD.
ENDCLASS.

DATA: go_obj TYPE REF TO c2.

START-OF-SELECTION.
  CREATE OBJECT go_obj.

  CALL METHOD go_obj->create.

2、继承与参照变量

        Class3 是 Class2 的子类,Class2 又是Class1 的子类。即右侧的对象都是 Class1 的实例。类的参照变量 Cref1、2、3 分别在参照 Class1、2、3 且都与对象连接在一起。但是只有 Cref1 才能指定 Class1的PUBLIC 组件地址。Cref2 可以指定 Class1 和 Class 2的PUBLIC 组件地址。Cref3 可以指定所有类的 PUBLIC 组件地址。

3、抽象/最终方法和类

        ABSTRACT 和 FINAL 语使用方法和类定义抽象、最终方法和类。抽象方法定义在抽象类中,但在类中无法实现功能,不过可以在类的子类中实现。抽象类无法初始化创建。Abstract 类不能用初始化创建。

4、类的构成要素和命名空间

这种超级类的组件中只显示 PUBLIC 和 PROTECTED 属性。所有 PUBLIC、PROTECTED 组件包含在继承树中,且属于同一个命名空间里。综上所述,存在于继承树上的组件都拥有唯一的名字。相反PRIVATE 组件却只在所属类中有唯一的名字。

        重新定义方法时,将相同名字的方法重新 IMPLEMENTATION 覆盖超级类的方法。但是重新定义的方法却无法替代原有的方法 IMPLEMENTATION。这是因为原超级类的方法名字已经以唯一的名字保留。前面已经提到,不是调用子类中重新定义的方法,而是调用超级类的原有方法时要使用 super-> 语句。这种符号称为 Pseudo Reference。 

5、继承与静态属性

        与类的所有构成要素一样,静态属性在各个继承树上只存在一个。子类可以访问超级类的 PUBLIC 和 PROTECTED 静态属性。相反,超级类可以与子类共享自己的 PUBLIC、PROTECTED 属性。在前面已经介绍,静态属性用 CLASS-DATA 语定义,而静态方法用CLASS-METHOD 语句定义。下面通过练习再仔细观察关于静态属性和方法。静态属性和方法是为了制作类的组件而定义的,即使不创建对象也会显示在内存中。即使创建对象使用静态属性和方法也不会发生错误,但不建议采用此法。

6、继承和构造函数

(1)实例构造函数:

        所有类都拥有实例构造函数,调用创建对象的构造函数时使用。前面提到,在继承树上的组件名字必须唯一,而构造函数却是例外事项。但是要谨记,这些类的实例构造函数在继承树上保持着完全独立的关系。

        在子类中不能重新定义超级类的实例构造函数,也不能使用CALL METHOD 构造函数语句。若使用此语句会生没有这个名字的错误信息。创建对象时系统会自动调用此函数。若子类包含超级类的 Visible 属性,则子类的实例构造函数可以调用超级类的实例构造函数。每个子类实例创建者需包含 CALLMEOTHD SUPER->Constructor语句。没有明确声明实例构造函数的超级类会默认调用实例构造函数。没有明确定义实例创建者的超级类会默认调用实例创建者。依此自动调用超级类的实例创建者。调用默认构造函数时有多个参数可供选择。

 (2)静态构造函数:

         所有类都包含了 class_constructor 静态构造函数。此方法在系统中已经存在,且使用类自身方法之前被调用,另外也没有参数。若在程序中已经指定子类地址(创建对象),则静态构造函数处于已执行状态。但执行子类静态构造函数之前必须执行所有超级类的静态构造函数。此函数在程序中只能调用一次。

五、接口

比较类和抽象类

        一般类可以通过初始化来创建对象 (CREATE OBJECT),但是抽象类不可以,只能从子类继承使用。因为抽象类没有实现功能的IMPLEMENTATION 部分。抽象类是将一些共通的功能集合在一个类中,然后继承此类在子类中使用

比较类和接口

        接口,如抽象类,不能直接通过初始化使用。然而可以追加到类中实现IMPLEMENTATION。类要实现接口的功能,只能通过接口实现。

比较抽象类和接口

        抽象类是在子类继承后才能实现自己具备的方法功能,而 ABAP 对象中只能单一继承,因此继承抽象类的子类不能再继承其他类。但是接口不属于继承,是在类中追加声明的概念因此可以多重继承。

1、定义接口

接口如同类,在 ABAP 程序中也可定义全局 (Global) 或局部 (Local) 接口。定义部分可以包含属性、方法、事件等所有项目。接口组件不必定义在访问权限领域中,是因为在类中追加接口时必须定义在 PUBLIC SECTION 中。另外在类中实现接口的方法,因此接口不能包含功能实现部分。

2、实现接口

在类中接口只能定义在 PUBLIC SECTION 中,因此实现接口的方法功能时,接口的组件会追加到类的 PUBLIC SECTION 中。换言之,上语句中接口 intf 的组件 meth 定义在类的IMPLEMENTATION 中,则类中会存在 intf-meth。如右上图语句所示,接口的方法可以在类中实现,即接口可以在其他类中实现其功能。

 3、参照接口

        参照变量可以访问对象。不用创建参照类的参照变量,只需定义参照接口的参照变量就可以访问对象。即若类中已经实现了接口 intf,则只用参照接口的参照变量就可以访问组件,意味着不必创建类的参照变量。

        接口通过 Reference 可以使多个类拥有统一形态。这称为多态性(Polymorphism)

例:

* 接口
INTERFACE account.     "定义接口
  METHODS calc.
  DATA balance TYPE i.
ENDINTERFACE.

CLASS c1 DEFINITION.
  PUBLIC SECTION.
    INTERFACES account.    "实现接口
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD account~calc.    "重写接口的方法
    WRITE : / 'deposit money is :',account~balance.
  ENDMETHOD.
ENDCLASS.

CLASS c2 DEFINITION.
  PUBLIC SECTION.
    INTERFACES account.    "实现接口
ENDCLASS.

CLASS c2 IMPLEMENTATION.
  METHOD account~calc.     "重写接口的方法
    WRITE: / 'withdrawl money id :',account~balance.
  ENDMETHOD.
ENDCLASS.

DATA:ref1 TYPE REF TO c1,
     ref2 TYPE REF TO c2,
     iref TYPE REF TO account.

START-OF-SELECTION.
create OBJECT:ref1,ref2.

ref1->account~balance = 300.        "赋值
CALL METHOD: ref1->account~calc.     "从ref1调用接口的方法

iref = ref1.            "接口参照ref1的属性和方法
CALL METHOD iref->calc.    "接口参照ref1调用方法calc

ref2->account~balance = '-200'.        "赋值
CALL METHOD: ref2->account~calc.     "从ref1调用接口的方法

iref = ref2.             "接口参照ref2的属性和方法
call METHOD iref->calc.   "接口参照ref2调用方法calc

4、使用别名

        所有接口组件可以利用ALIAS 指定其别名 (Alias Name)。在接口内再调用其他接口的Deep 组件经常使用。ALIAS 只能在接口内或者类的定义部分使用,不能在实现方法功能的ATION 中使用。

例:

*使用别名
INTERFACE account.
  METHODS calc IMPORTING p1 TYPE i.
ENDINTERFACE.

CLASS c1 DEFINITION.
  PUBLIC SECTION.
    INTERFACES account.
    ALIASES calc FOR account~calc.   "使用别名,方便调用
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD account~calc.
    WRITE : / 'deposit money is :',p1.
  ENDMETHOD.
ENDCLASS.

DATA:ref TYPE REF TO c1.

START-OF-SELECTION.
  CREATE OBJECT:ref.

  CALL METHOD:ref->calc EXPORTING p1 = 200.   "使用别名调用

 六、事件

        在 ABAP 对象中在没有继承关系的类之间,从一个类的方法中调用另一个类的方法时需要使用事件来控制。在类中定义事件时类的方法可以触发事件,这与 Event Handler 交替启动。

1、触发事件

(1)声明事件

        在类或接口的声明部分首先声明事件。用以下语句声明实例事件。静态事件使用

CLASS-EVENT 语句。

1)实例事件:

2)静态事件:

        可利用 CLASS-EVENTS 语声明静态事件。所有方法都能调用静态事件。静态事件是在静态方法中可以调用的唯一事件类型。

(2)Triggering Event

        类内部的实例事件在类的所有实例中都可以触发。静态事件在所有方法中都可以触发但是只有静态方法才能触发静态事件。

2、Handing Event

(1)声明事件处理器方法(Event Handing Method)

 (2)注册事件处理器方法

        在静态事件中无法使用 FOR 语句。 

(3)Raise Event

        调用 RAISE EVENT 语句开始执行下一个阶段之前,执行所有被注册的处理器方法(Synchronous Event handling)。若处理器方法触发的是自身事件,则执行原有的处理器方法之前,执行自身处理器方法。为了防止发生无限循环,将其控制为只执行 64 次循环。处理器方法按照注册的顺序执行。若动态地执行事件处理器,则无法预测其执行顺序。此时只能理解为同时执行所有事件处理器来进行编码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/72707.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apache+PHP+MariaDB+MQTT重启指令

启动PHP服务 1.启动 systemctl start php-fpm.service Apache服务 1. 启动、终止、重启 systemctl start httpd.service #启动 systemctl stop httpd.service #停止 systemctl restart httpd.service #重启 2. 设置开机启动/关闭 systemctl enable httpd.service #开机…

Spring【日志文件的打印与输出】

Spring【日志文件的打印与输出】&#x1f34e;一.日志文件&#x1f352;1.1 日志的作用&#x1f352;1.2 怎样查看到日志信息&#x1f34e;二. 打印日志&#x1f352;2.1 自定义打印日志&#x1f352;2.2 ⽇志格式说明&#x1f34e;三.日志级别&#x1f352;3.1 日志级别的作用…

SpringMVC的收参方式?

第一种收取参数方式&#xff1a;数据类型收取参数 第二种收取参数的方式&#xff1a;实体类收取参数&#xff08;传参&#xff09; 第三种收取参数的方式&#xff1a;ajax 收取数组/集合 第四种收取参数的方式&#xff1a;ajax 接收json数据 第五种收取参数的方式&#xff1a;…

全网最牛最全Postman接口测试(五): postman设置接口关联,postman实现参数化

Postman(9): postman设置接口关联 postman设置接口关联 在实际的接口测试中&#xff0c;后一个接口经常需要用到前一个接口返回的结果&#xff0c; 从而让后一个接口能正常执行&#xff0c;这个过程的实现称为关联。 在postman中实现关联操作的步骤如下&#xff1a; 1、利用…

怎样避免软件测试中的漏测

什么是测试漏测&#xff1f; 测试漏测是指软件产品在测试结束后出现了在测试过程中没有被发现的bug。我们知道&#xff0c;漏测是每一个软件测试者最头疼的事&#xff0c;一旦出现漏测&#xff0c;首先给客户带来了非常不好的影响&#xff0c;特别是严重的功能性bug被漏测&…

程序员如何创造睡后收入呢?

程序员作为一个互联网行业的职业&#xff0c;在互联网当道的现在是非常吃香的。 作为程序员&#xff0c;一个基础工资的收入就已经是一笔不菲的收益了。 然而&#xff0c;钱总是不够花的&#xff0c;毕竟捂住口袋有点小难。 这时候&#xff0c;我们只好把视线转向另一边&…

算法面试题——删除链表后第N个节点

给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[] 示例 3&#xff…

C语言百日刷题第十三天

前言 今天是刷题第13天&#xff0c;放弃不难&#xff0c;但坚持一定很酷~ 临近期末&#xff0c;再刷一套模拟题 C语言百日刷题第十三天前言选择题判断题编程题选择题 1.若由定义int*p1,*p2,m5,n;以下赋值语句都正确的选项是&#xff08;&#xff09; A、p1&m;p2&n…

signintech/gopdf功能介绍与代码示例

signintech/gopdf功能介绍与代码示例 PDF相关常识以及signintech/gopdf功能概览 代码示例&#xff1a; 参考&#xff1a;https://gitee.com/ixuer/gopdf_example 代码示例包括&#xff1a; 设置页面配置&#xff0c;如宽度和高度。test/font: 添加ttf字体&#xff0c;并设置…

计算机毕业设计springboot+vue基本微信小程序的快递收发小程序

项目介绍 随着Internet的发展,人们的日常生活已经离不开网络。未来人们的生活与工作将变得越来越数字化、网络化和电子化。本文以实际运用为开发背景,运用软件工程原理和开发方法,它主要是采用java语言技术、springboot框架和微信小程序来完成对系统的设计。整个开发过程首先对…

element-ui的Dropdown下拉菜单,传递多个参数

element-ui的Dropdown下拉菜单&#xff0c;传递多个参数 原因&#xff1a; Dropdown下拉菜单只允许我们传递一个参数 解决步骤: 在允许我们传递一个参数的哪里提前调用方法: 以前&#xff1a;<el-dropdown-item command"a"> 测试 </el-dropdown-item> 现…

一文揭密字节跳动薪资职级,资深测试开发居然能拿......

曾经的互联网是PC的时代&#xff0c;随着智能手机的普及&#xff0c;移动互联网开始飞速崛起。而字节跳动抓住了这波机遇&#xff0c;2015年&#xff0c;字节跳动全面加码短视频&#xff0c;从那以后&#xff0c;抖音成为了字节跳动用户、收入和估值的最大增长引擎。 自从字节逐…

Docker 基础和常用命令总结

一&#xff0c;Docker 简介 1.1&#xff0c;什么是 Docker1.2&#xff0c;Docker 与虚拟机的区别1.3&#xff0c;Docker 架构1.4&#xff0c;为什么用 Docker 二&#xff0c;Docker 基本概念 2.1&#xff0c;镜像2.2&#xff0c;容器2.3&#xff0c;仓库 三&#xff0c;Docker …

【记录】网站变灰色怎么实现?

最近&#xff0c;大家应该注意到了&#xff0c;各大网站和APP都变成灰色了。原因也很简单&#xff0c;一般在清明节、全国哀悼日、大地震的日子、以及一些影响力很大的伟人逝世或纪念日的时候使用&#xff0c;使用后的网站的网页变成灰色(黑白色)&#xff0c;以表示对逝者的悼念…

补贴来了 | 人社部:获得这些证书,国家有补贴

近期&#xff0c;人社部等3部门发布《关于做好失业保险稳岗位提技能防失业工作的通知》&#xff0c;通知提出拓宽技能提升补贴受益范围&#xff1a; 1.领取失业保险金人员取得职业资格证书或职业技能等级证书的&#xff0c; 可按照初级(五级)不超过1000元、中级(四级)不超过150…

流程引擎activiti太难?(看这篇就够了)

一、工作流介绍 1、概念 工作流(Workflow)&#xff0c;就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程&#xff0c;从而实现某个预期的业务目标&#xff0c;或者促使此目标的实现”。 …

[附源码]Python计算机毕业设计Djang基于vuejs的文创产品销售平台app

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

MPLS协议介绍

MPLS介绍 1.MPLS协议概述 MPLS根据自己的标签交换&#xff0c;需要给数据包先写上自己的标签&#xff0c;然后设备才能查看标签之后就转发&#xff0c;此标签是需要在原有的数据包的基础上加进去的&#xff0c;并没有将以前的包头删除&#xff0c;MPLS的标签加在了第二层帧的…

数据仓库规范建设指南

数据仓库规范建设指南 1.数仓公共开发规范 1.1 层次调用规范 稳定业务按照标准的数据流向进行开发&#xff0c;即ODS-> DWD-> DWS-> APP。 非稳定业务或探索性需求&#xff0c;可以遵循ODS-> DWD->APP或者ODS-> DWD-> DWM-> APP 两个模型数据流。 …

国际物流概述:国际物流的流程是什么?

国际运输有很多参与者:航运公司、预订代理、国际货运代理和报关行;本文主要介绍托运人、收货人、国际货运代理和航运公司这四大LCL运输的参与者。从托运人到收货人的货物运输有五个物理流程和两个单证流程&#xff0c;每次装运都需要进行。每个流程都有相关的费用&#xff0c;必…