ABAP中的类与对象(Local class )

7 篇文章 0 订阅

1 Definition

1.1 What is the object?

类->类型 , 对象->个体
要使用所需功能的对象,首先要经过根据类定义对象的过程。
根据类创建对象的过程成为实例化,根据类创建的对象为示例

Class: 类是创建对象的模板
Object: 对象是指商品/物体/对象/目的,是类的实例

1.2 Differentiation of classes

全局类(Global): 使用事务代码 SE24
存储在类池中(Class Library in the Repository)
所有ABAP程序都可以对其访问
本地类(Local)
在程序中定义
只有该程序可以使用

2 Factor of class

2.1 classification

Instance-specific component
参照类创建对象时,内存中存在的项目,每次创建对象时都会被初始化,各个类的对象中存在 。
声明方式:属性: Data; 方法: METHODS. 访问: OBJECT->COMP

Static component
遇到创建类的语句(CREATE OBJECT)开始, 直到程序结束都存储于内存中,是依赖类存在的项目。即使不创建对象,若已存在内存中既可以直接使用。
声明方式:属性:CLASS-DATA; 方法: CLASS-METHODS. 访问:CLASS=>COMP

2.2 Class Definition

Attributes
可以拥有ABAP所有数据类型的类内部数据字段,对象状态由属性决定。 DATA/CONSTANTS

Method
用来定义决定对象行为的类内部执行步骤,可以访问类的所由属性,可通过方法修改对象的内容,另外,方法提供传入传出参数,便于用户交互 。

Event
事件是没有继承关系的类之间可以互相调用彼此方法的特殊方法

在这里插入图片描述

3 Access area

Public Section. (共有部分)
内部可见,外部可见
Public 部分的组件,构成类与用户的接口
Protected Section.保护部分
内部可见,继承可见, 外部不可见
PROTECTED部分的组件,构成继承类之间的接口
Private section.私有部分
. 内部可见,继承不可见,外部不可见

在这里插入图片描述

4 Create local class

4.1 Define the project of class (Attributes , Method, Event)

CLASSDEFINITION.
. 要素声明
. 所有项目都需要定义在三个访问区域之一中
ENDCLASS.

4.2 Implement method of class
     CLASS <class> IMPLEMENTATION.
     ENDCLASS .

5 Call method

5.1 Basic syntax
       METHOD <meth>
       IMPORTING ...<I1> TYPE <type>...
       EXPORTING...<e1> TYPE <type>...
       CHANGING...<c1>  TYPE <type>...
       EXCEPTIONS ...X1...
      CALL METHOD [OREF->| class=>] meth
       EXPORTING...I1 = f1...
       RECEIVING R = H.
       -IMPORT/EXPORT :数据输入/数据接口, 接口参数可以参考单个变量,结构,要么内表
       -CHANGING, 同时作为输入输出接口,接口参数可以参考单个变量,结构,内表; 
       -RETURNING: 返回类传递数值。该定义不能和CHANGING/EXPORTING同时使用
       -EXCEPTIONS:返回执行中所出现的错误
5.2 Attention

类函数可以拥有多个输入参数, 但只能由一个输出参数。类的输出接口参数必须与类函数中所定义的类型保持一致。

当方法没有输出参数(EXPORTING)的时候可以通过以下方式调用:

  • CALL METHOD meth()," 没有输入参数
  • CALL METHOD meth(a)."一个输入
  • CALL METHOD meth(f1 = a1… fn =an)."N个输入。

6 CONSTRUCTOR Method

6.1 CONSTRUCTOR METHOD
 - 在实例化对象时,自动化完成对象的初始化,这个对象是空的; 
 - 如果希望每一个对象都为其初始化某些特征,需要用到构造方式。
 - 没有返回数据类型,功能是在实例化类时完成一些初始化工作。
         .使用METHODS CONSTRUCTOR定义
         . 使用CLASS-METHODS CLASS-CONSTRUCTOR定义
  - 每个类只能有一个构造方法,在CREATE OBJECT语句中自动调用构造方法
6.2 WHEN
 - 需要分配 (外部)资源
 - 需要初始化一些不能用DATA语句的VALUE指定的属性值
 - 需要修改静态属性
 - 通常不能显式的调用构造器

7 Inheritance of class

7.1 Definition
 - 继承的本质就是代码重用。当要构造一个新类时,无需从零开始,可以参考一个已有类,在其基    础上建立一个新类。
 - 参考类: 基类/父类。新建类: 派生类/子类
 - 派生类可以继承基类所有的属性和方法,并可以在次基础上添加新的特性
7.2 Usage
- CLASS <subclass> DEFINITION INHERITING FROM <superclass>.
7.3 Polymorphism IMPLEMENTATION.
  • 由于每个派生类的属性不同,相同的基类对象在不同的派生类中需要以不同的方式来
    表现,因此提供多态的概念。
    -在派生类中定义和基类的相同的接口,但是可以使用不同的代码来实现。
7.4 Usage
  • METHOD REDEFINITION.
    -在派生类中使用基类的方法,使用SUPER : CALL METHOD SUPER->.
    -重载方法,使用ME:CALL METHOD ME ->.

8 ABSTRACT CLASS

8.1 Abstract class
   -  含有一个要么多个方法的类,称为抽象类
   - 抽象类不能使用CREATE OBJECT 语句创建实例对象
   - 仅包含没有具体实现的方法
         . CLASS<class> DEFINITION ABSTRACT . /ENDCLASS.
8.2 Abstract method
-  仅包含方法定义,但没有具体实现的方法,需要通过派生类来实现
 . METHODS <meth> ABSTRACT .

9 End class

9.1 Don’t Inherit

防止由于设计中多级别派生造成类造成的语法和语义的冲突

9.2 Usage
  • class DEFINITION FINAL ./ ENDCLASS .
  • METHODS final.

10 Interface

10.1 interface
  • 和抽象类相似,定义了一些未实现的属性和方法,所有继承它的类都继承这些成员
  • 不需要方法实现,不能直接实例化
  • 接口所有成员都是抽象的
  • 接口成员一般是共有的
  • 接口中不能含有构造方法
10.2 Usage
  • INTERFACE.
    data…
    method…
    ENDINTERFACE.
    CLASS DEFINITION
    PUBLIC SECTION
    INTERFACES: int1, int1.
    ENDCLASS.
10.3 intf=>const

静态成员访问时,通过接口引用访问 intf=>const

  • 其他成员,可以通过实现该接口的类本身,要么类引用进行访问
    .class=>intf~attr. CALL METHOD class=>intf-meth.
10.4
  • 直接调用接口方法,必须使用循环
10.5
  • 别名 :ALIASES alias FOR INTF-COM1.

11 Event

11.1 Event
  - 用于捕获某类对象状态的改变来触发事件的方法,并进行处理
11.2 Definition
  • EVENTS| CLASS-EVENTS evt
    
  • EXPORTING ... VALUE(P1) type | LIKE f [optional | DEFAULT g]...
    
  • 实例事件中包含一个隐含参数SENDER,该参数的类型为触发事件的类或接口对     象引用
    
11.3 Trigger
  • 一个实例事件可以被类中的任意方法触发,静态事件则可以被静态方法触发
    
  • RAISE EVENT evt EXPORTING P1 = F1 ... PN = fn
    
11.4 Deal event
  • 事件需要通过触发其申明代码中所定义的方法才能处理相关事务。人和类都可以调用其他类中所定义的事件,或调用自身所定义的事件
  • METHODS | CLASS-METHODS
    meth FOR EVENT evt of cif IMPORTING … ei …
    -为相关的事件注册方法
    SET HANDLER …hi… [FOR]…
11.5 Classification
  • 事件类型分为4种
    • 定义在类中的: 实例事件,静态事件
    • 定义在接口中:实例事件,静态事件
  • 对于实例事件,注册语句必须使用FOR指定注册对象
    • … FOR ref.
    • … FOR ALL INSTANCES(注册所有可以触发该事件的实例,包括尚未被创建的实例)
  • 注册静态事件,不需要FOR后缀,自动应用于整个类
  • 当程序执行到RAISE EVENT语句后,所有已注册的处理方法都将在下一个语句之前被处理。处理方法按照其在系统内部注册的顺序被执行。为避免无限循环,目前事件处理最多不能超超过64级嵌套

12.Demo

*&---------------------------------------------------------------------*
*& Report ZJGLTET01
*&---------------------------------------------------------------------*
*&  Content : Orject oriented , Create local class
*&---------------------------------------------------------------------*
REPORT ZJGLTET01.

INTERFACE INTER.
  METHODS WRITE_INTER.
ENDINTERFACE.

" Define project of class.
CLASS LCL_COMPT DEFINITION.


  PUBLIC SECTION.
    TYPES   GTY_CHAR20 TYPE C LENGTH 20.
    TYPES   GTY_CHAR5 TYPE C LENGTH 5.
* instance attrubities
    DATA GV_CHAR TYPE C LENGTH 20 VALUE '实例属性 '.
    DATA GV_CONCATENATE TYPE GTY_CHAR20.
    CONSTANTS C_DATA TYPE C LENGTH 20 VALUE '常量' .
    TYPES  GTY_P02  TYPE P LENGTH 10  DECIMALS 2.
    DATA GS_SCHOOL TYPE ZSCHOOL_HQ_04.

* INSTANCE METHOD.
    METHODS WRITE_CHAR.
    METHODS WRITE_INSTANCE.
    METHODS SET_VALUE IMPORTING I_value TYPE GTY_CHAR20.        " 对CHANGE变量赋值
    METHODS GET_VALUE EXPORTING  E_VALUE TYPE GTY_CHAR20.        " 获取CHANGE变量的值
    METHODS CON_VALUE IMPORTING I_VALUE1 TYPE GTY_CHAR5 OPTIONAL
                                I_VALUE2 TYPE GTY_CHAR5
                                I_VALUE3 TYPE GTY_CHAR5
                      EXPORTING E_SUBRC  TYPE C
                                E_CONCAT TYPE GTY_CHAR20.  " 多个参数
    METHODS RET_VALUE IMPORTING I_VALUE1        TYPE GTY_CHAR5 OPTIONAL
                                I_VALUE2        TYPE GTY_CHAR5
                                I_VALUE3        TYPE GTY_CHAR5
                      RETURNING VALUE(E_CONCAT) TYPE GTY_CHAR20.

    METHODS GET_ROUND_01  IMPORTING  VALUE(I_R)     TYPE GTY_P02
                          EXPORTING  VALUE(E_ROUND) TYPE GTY_P02
                          EXCEPTIONS NO_ZERO .

    METHODS GET_ROUND_02  IMPORTING VALUE(I_R)     TYPE GTY_P02
                                    VALUE(I_PI)    TYPE GTY_P02
                          RETURNING VALUE(E_ROUND) TYPE GTY_P02 .


    METHODS GET_DATA IMPORTING P_SCHOOL LIKE   GS_SCHOOL-ZSCHOOL.

    METHODS ADD_DATA.

* STATIC METHOD
    CLASS-METHODS  WRITE_STATIC .
    METHODS CONSTRUCTOR IMPORTING  I_CHAR TYPE GTY_CHAR20.

    INTERFACES INTER.
    ALIASES WRITE_INTERFACE FOR INTER~WRITE_INTER .

    EVENTS DATA_EXIST EXPORTING VALUE(PS_SCHOOL) LIKE   GS_SCHOOL .
    EVENTS  MOD_10  EXPORTING VALUE(P_INT) TYPE I .

  PROTECTED SECTION.
    CLASS-DATA GV_SUPER TYPE C LENGTH 20 VALUE 'SUPER CLASS' .
    CONSTANTS C_PI TYPE GTY_P02 VALUE '3.14'.

  PRIVATE SECTION.
* static attrubities

    CLASS-DATA GV_STATIC TYPE C LENGTH 20 VALUE '静态属性 '.
    CLASS-DATA GV_CHANGE TYPE C LENGTH 20.

    DATA GV_INT TYPE I .
ENDCLASS.
* INHERIT CLASS
CLASS LCL_SUB DEFINITION INHERITING FROM LCL_COMPT.
  PUBLIC SECTION.
    METHODS WRITE_SUPER.
    METHODS GET_ROUND_02 REDEFINITION.
    METHODS CALCULATE_CIRCLE IMPORTING I_R TYPE GTY_P02.

ENDCLASS.


CLASS LCL_HANDLER DEFINITION.
  PUBLIC SECTION.
    METHODS WRITE_DATA FOR EVENT DATA_EXIST OF LCL_COMPT
      IMPORTING PS_SCHOOL.

    METHODS WRITE_INT FOR EVENT MOD_10 OF LCL_COMPT
                      IMPORTING P_INT .

ENDCLASS.




CLASS LCL_HANDLER IMPLEMENTATION.
  METHOD WRITE_DATA.

    WRITE: / PS_SCHOOL-ZSCHOOL, PS_SCHOOL-ZSNAME, PS_SCHOOL-ZADD.

  ENDMETHOD.
   METHOD WRITE_INT.

     WRITE: / P_INT.


  ENDMETHOD.

ENDCLASS .


* Define content of class.

CLASS LCL_COMPT IMPLEMENTATION.
  METHOD WRITE_CHAR.

    WRITE : /'实例方法:', GV_CHAR.

  ENDMETHOD.

  METHOD WRITE_STATIC.
    WRITE : /'静态方法:' ,GV_STATIC.
  ENDMETHOD.

  METHOD WRITE_INSTANCE.
    WRITE : /'静态方法:' ,GV_STATIC.
  ENDMETHOD.
  METHOD SET_VALUE.
    GV_CHANGE = I_VALUE .

  ENDMETHOD.
  METHOD GET_VALUE.
*    GV_CHANGE = E_VALUE .
    E_VALUE =  GV_CHANGE.

  ENDMETHOD.
  METHOD CON_VALUE.
    CONCATENATE  I_VALUE1 I_VALUE2  I_VALUE3 INTO GV_CONCATENATE.
    IF SY-SUBRC = 0.
      E_SUBRC = 'S'.
      E_CONCAT = GV_CONCATENATE.
    ELSE.
      E_SUBRC = 'E'.
    ENDIF.
  ENDMETHOD.
  METHOD RET_VALUE.

    CONCATENATE  I_VALUE1 I_VALUE2  I_VALUE3 INTO GV_CONCATENATE.
    IF SY-SUBRC = 0.

      E_CONCAT = GV_CONCATENATE.
    ELSE.

    ENDIF.

  ENDMETHOD.
  METHOD GET_ROUND_01.
    IF I_R < 0.
      RAISE NO_ZERO.
    ENDIF.

    E_ROUND = C_PI * ( I_R ** 2 ).

  ENDMETHOD.

  METHOD GET_ROUND_02.


    E_ROUND = I_PI * ( I_R ** 2 ).


  ENDMETHOD.
  METHOD CONSTRUCTOR.
    WRITE:/'执行了构造器函数' .
    WRITE : I_CHAR.
  ENDMETHOD.

  METHOD WRITE_INTERFACE.

    WRITE: / '接口中的方法' .
  ENDMETHOD.
  METHOD GET_DATA.
    SELECT SINGLE *
      FROM ZSCHOOL_HQ_04
      INTO CORRESPONDING FIELDS OF GS_SCHOOL
      WHERE ZSCHOOL = P_SCHOOL .
    IF SY-SUBRC = 0.
      RAISE EVENT DATA_EXIST
       EXPORTING
         PS_SCHOOL = GS_SCHOOL .
    ELSE.

      WRITE: / '取数失败' .

    ENDIF.
    ENDMETHOD.
     METHOD ADD_DATA.
       DATA LV_MOD TYPE I.
       GV_INT = GV_INT + 1 .
       LV_MOD = GV_INT MOD 10 .
       IF LV_MOD  = 0.
         RAISE EVENT MOD_10  EXPORTING P_int = GV_INT .

       ENDIF.
     ENDMETHOD.






ENDCLASS.

* INHERIT CLASS
CLASS LCL_SUB IMPLEMENTATION.
  METHOD WRITE_SUPER.
    WRITE: / 'PUBLIC SECTION:' , GV_CHAR.
    WRITE: / 'PROTECT SELECTION:', GV_SUPER.
*   WRITE: / 'PRIVATE SELECTION:', GV_STATIC.
  ENDMETHOD.

  METHOD GET_ROUND_02.
    DATA LV_CIRCLE  TYPE P LENGTH 2.
    CALL METHOD SUPER->GET_ROUND_02
      EXPORTING
        I_R     = I_R
        I_PI    = '3.14'
      RECEIVING
        E_ROUND = LV_CIRCLE.
    WRITE : / LV_CIRCLE.

    E_ROUND = 2 * C_PI * I_R.

    LV_CIRCLE = E_ROUND.
    WRITE :/ '周长' , LV_CIRCLE .
  ENDMETHOD.
  METHOD CALCULATE_CIRCLE.

    DATA LV_SPACE TYPE P LENGTH 2.


    CALL METHOD ME->GET_ROUND_02
      EXPORTING
        I_R     = I_R
        I_PI    = '3.14'
      RECEIVING
        E_ROUND = LV_SPACE.
    WRITE : / LV_SPACE.


  ENDMETHOD.

ENDCLASS.


*Declaration object

DATA LCL_OBJECT TYPE REF TO LCL_COMPT.  " Instance.
DATA LCL_OBJECT_2 TYPE REF TO LCL_COMPT.  " Instance.

CLASS LCL_ABSTRACT DEFINITION ABSTRACT.
  PUBLIC SECTION.
*  METHODS WRITE_ABSTRACT.
    METHODS WRITE_ABSTRACT_02 ABSTRACT.

ENDCLASS.



*CLASS LCL_ABSTRACT IMPLEMENTATION.
*  METHOD WRITE_ABSTRACT.
*    WRITE:/ '抽象类中的实例方法' .
*
*  ENDMETHOD.

*
*ENDCLASS.
CLASS LCL_SUB_02 DEFINITION INHERITING FROM LCL_ABSTRACT .
  PUBLIC SECTION.
    METHODS WRITE_ABSTRACT_02 REDEFINITION.


ENDCLASS.

CLASS LCL_SUB_02  IMPLEMENTATION.

  METHOD WRITE_ABSTRACT_02 .

    WRITE : / '抽象类中的抽象方法' .

  ENDMETHOD.


ENDCLASS.



START-OF-SELECTION.
  CREATE OBJECT LCL_OBJECT
    EXPORTING
      I_CHAR = '实例1'.
  CREATE OBJECT LCL_OBJECT_2
    EXPORTING
      I_CHAR = '实例2'.
* Atrubutite of Instance is different in dirrerent instance.
  WRITE:/ '访问实例属性:' ,LCL_OBJECT->GV_CHAR. " Acess instance atrubutite.
  LCL_OBJECT->GV_CHAR = '更换CHAR的值' . " Modify the atrubutite of instance1
  CALL METHOD LCL_OBJECT->WRITE_CHAR. " instance1 value
  CALL METHOD LCL_OBJECT_2->WRITE_CHAR. " insance2 value

* ACCESS Static ATRUBUTITE.
*WRITE:/ '访问静态属性:' , LCL_COMPT=>GV_STATIC.
*LCL_COMPT=>GV_STATIC  = '更换静态属性的值' .
  CALL METHOD LCL_COMPT=>WRITE_STATIC.
  CALL METHOD LCL_OBJECT->WRITE_INSTANCE. " Instance Method.
  CALL METHOD LCL_OBJECT_2->WRITE_INSTANCE. " Instance Method.

  DATA  GV_DATA TYPE LCL_OBJECT->GTY_CHAR20.
*带有参数的方法的调用
  CALL METHOD LCL_OBJECT->SET_VALUE
    EXPORTING
      I_VALUE = '赋值CHAR变量'.
  CALL METHOD LCL_OBJECT->GET_VALUE
    IMPORTING
      E_VALUE = GV_DATA.

  WRITE: / GV_DATA .


  DATA GV_SUBRC TYPE C.
  CALL METHOD LCL_OBJECT->CON_VALUE
    EXPORTING
*     I_VALUE1 = 'CHINA'
      I_VALUE2 = 'BJ'
      I_VALUE3 = 'GREAT'
    IMPORTING
      E_SUBRC  = GV_SUBRC
      E_CONCAT = GV_DATA.

  WRITE:/ GV_SUBRC, GV_DATA.


  CALL METHOD LCL_OBJECT->RET_VALUE
    EXPORTING
      I_VALUE1 = 'CHINA'
      I_VALUE2 = 'BJ'
      I_VALUE3 = 'GREAT'
    RECEIVING
      E_CONCAT = GV_DATA.
  WRITE:/ GV_DATA.

  " 访问常量
  WRITE : / LCL_COMPT=>C_DATA.
  WRITE:/ LCL_OBJECT->C_DATA.

  PARAMETERS P_R TYPE P LENGTH 10 DECIMALS 2.

  DATA GV_ROUND TYPE P LENGTH 10 DECIMALS 2.
  CONSTANTS C_PI TYPE P LENGTH 10 DECIMALS 2 VALUE '3.14' .
  CALL METHOD LCL_OBJECT->GET_ROUND_01
    EXPORTING
      I_R     = P_R
    IMPORTING
      E_ROUND = GV_ROUND
    EXCEPTIONS
      NO_ZERO = 1.
  IF SY-SUBRC = 1.
    WRITE:/ '半径不能小于0' .

  ENDIF.

*   WRITE: / gv_round .
*  CALL METHOD lcl_object->get_round_02
*    EXPORTING
*      i_r      = p_r
*    RECEIVING
*      e_round = gv_round.


  GV_ROUND = LCL_OBJECT->GET_ROUND_02( I_R = P_R
                                       I_PI = C_PI ).
  WRITE: / GV_ROUND .

  DATA : OBJECT_SUB TYPE REF TO  LCL_SUB.
  CREATE OBJECT OBJECT_SUB
    EXPORTING
      I_CHAR = '子类实例化'.
  CALL METHOD OBJECT_SUB->GET_ROUND_02
    EXPORTING
      I_R     = P_R
      I_PI    = '3.14'
    RECEIVING
      E_ROUND = GV_ROUND.

  CALL METHOD LCL_OBJECT->WRITE_INTERFACE.




  DATA EVENT_HANDLER TYPE REF TO  LCL_HANDLER.
  DATA EVENT_HANDLER_2 TYPE REF TO  LCL_HANDLER.
  DATA OBJECT_SUB_2 TYPE REF TO LCL_SUB.
  CREATE OBJECT EVENT_HANDLER.
  CREATE OBJECT EVENT_HANDLER_2.
  CREATE OBJECT OBJECT_SUB_2
  EXPORTING
           I_CHAR = 'CREATE' .
  SET HANDLER EVENT_HANDLER->WRITE_DATA FOR LCL_OBJECT.
  SET HANDLER EVENT_HANDLER->WRITE_DATA FOR LCL_OBJECT_2.
  SET HANDLER EVENT_HANDLER_2->WRITE_DATA FOR LCL_OBJECT_2.
  SET HANDLER EVENT_HANDLER->WRITE_DATA FOR OBJECT_SUB_2 .
  SET HANDLER EVENT_HANDLER->WRITE_INT FOR LCL_OBJECT.

  CALL METHOD LCL_OBJECT->GET_DATA
    EXPORTING
      P_SCHOOL = '001'.

   CALL METHOD LCL_OBJECT_2->GET_DATA
    EXPORTING
      P_SCHOOL = '002'.

     WRITE : / '调用子类汇总'.
      CALL METHOD OBJECT_SUB_2->GET_DATA
    EXPORTING
      P_SCHOOL = '002'.

      DO 50 TIMES .

        CALL METHOD LCL_OBJECT->ADD_DATA.
      ENDDO.
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值