美文网首页ABAP开发
程序中声明的类练习

程序中声明的类练习

作者: 扇动蝴蝶的翅膀 | 来源:发表于2019-07-24 15:50 被阅读0次
    • 程序名:YTST_PPJLI_OO
    *&---------------------------------------------------------------------*
    *& Program   Name    :ZLPJ_OO
    *& Title          : 面向对象
    *& Module    Name      : OO
    *& Author           :PPJLI
    *& Create    Date     :12.07.2019 20:52:07
    *& Program   Type     :Report Program
    *& Requested by     :开发项编号
    *& Description     :面向对象的,创建本地类
    *&------------------- -------------------------------------------------*
    
    REPORT YTST_PPJLI_OO.
    
    *--------------------------------------------------------------------*
    *实例组件:声明方式(属性:data;      方法:method;      访问:object->comp)
    *静态组件:声明方式(属性:class-data;方法:class-method;访问:class=>comp)
    *两个组件之间的区别:实例组件依附于实例,不同的实例之间相互独立;静态组件存在于类中
    *--------------------------------------------------------------------*
    *&---------------------------------------------------------------------*
    *&  接口的定义
    *&---------------------------------------------------------------------*
    INTERFACE INTER.
      METHODS WRITE_INTER.
    ENDINTERFACE.
    
    
    *  DEFINITION:定义类中的项目(属性,方法,事件; 公有、私有、保护、友好)
    CLASS LCL_COMPT DEFINITION.
    *  &---------------------------------------------------------------------*
    *  &  *指明类中项目的访问区域,知道遇到下一个访问区域,该访问区域停止
    *  &---------------------------------------------------------------------*
      PUBLIC SECTION.
      TYPES: CTY_CHAR20 TYPE C LENGTH 20.
      TYPES: CTY_CHAR5  TYPE C LENGTH 5.
      TYPES: GTY_P02    TYPE P LENGTH 10 DECIMALS 2.
      "实例属性
      DATA GV_CHAR TYPE C LENGTH 20 VALUE '实例属性'.
      DATA:GV_CONCATENATE TYPE CTY_CHAR20.
    
    *  定义一个工作区 参照类型为学校数据库表
      DATA: GS_SCHOOL TYPE ZSCHOOL_LPJ_01.
    
      CONSTANTS C_DATA TYPE C LENGTH 20 VALUE '常量'.
      "实例方法
      METHODS WRITE_CHAR.
      METHODS WRITE_INSTANGE.
    
      METHODS SET_VALUE IMPORTING I_VALUE  TYPE CTY_CHAR20.         "用于外部参数的调用;  对GV_CHANGE进行赋值  引入参数P_VALUE
      METHODS GET_VALUE EXPORTING E_VALUE TYPE CTY_CHAR20.         "获取GV_CHANGE的值
    
      METHODS CON_VALUE IMPORTING I_VALUE1 TYPE CTY_CHAR5 OPTIONAL  "OPTIONAL可选参数
                                  I_VALUE2 TYPE CTY_CHAR5
                                  I_VALUE3 TYPE CTY_CHAR5
                        EXPORTING E_SUBRC  TYPE C
                                  E_CONCAT TYPE CTY_CHAR20.         "多个参数
      METHODS GET_DATA  IMPORTING P_SCHOOL LIKE GS_SCHOOL-ZSCHOOL.
    *&---------------------------------------------------------------------*
    *&  返回参数
    *&    1. returning不能和changing和exporting同时使用;
    *&      2. 只能接收一个返回参数
    *&---------------------------------------------------------------------*
      METHODS RET_VALUE IMPORTING I_VALUE1 TYPE CTY_CHAR5 OPTIONAL  "OPTIONAL可选参数
                                  I_VALUE2 TYPE CTY_CHAR5
                                  I_VALUE3 TYPE CTY_CHAR5
                        RETURNING VALUE(E_CONCAT) TYPE CTY_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 ADD_DATA.
    
    " 静态方法
      CLASS-METHODS WRITE_STATIC.
    " 静态属性
      CLASS-DATA GV_STATIC TYPE C LENGTH 20 VALUE '静态属性'.
    
    " 构造器方法
      METHODS CONSTRUCTOR IMPORTING I_CHAR TYPE CTY_CHAR20.
    
    *  接口的引用
      INTERFACES INTER.
    *  接口别名的声明
      ALIASES WRITE_INTERFACE FOR INTER~WRITE_INTER.
    
    *  事件
      EVENTS DATA_EXIST EXPORTING VALUE(PS_SCHOOL) LIKE GS_SCHOOL.  "因为GS_SCHOOL是一个对象不是类型,所以用like
      EVENTS MOD_10     EXPORTING VALUE(P_INT) TYPE I.
    
      PROTECTED SECTION.
    "    声明静态属性
         CLASS-DATA GV_SUBER TYPE C LENGTH 20 VALUE 'SUPER CLASS'.
         CONSTANTS C_PI TYPE GTY_P02 VALUE '3.14'.
    
    
      PRIVATE SECTION.
      "静态属性
      CLASS-DATA GV_STATIC_PRI TYPE C LENGTH 20 VALUE '私有静态属性'.
      CLASS-DATA GV_CHANGE     TYPE CTY_CHAR20.
    
      DATA: GV_INT TYPE I.
    
    ENDCLASS.
    
    *  IMPLEMENTATION:定义类中的方法的内容
    CLASS LCL_COMPT IMPLEMENTATION.
      METHOD WRITE_CHAR.
        WRITE:/ '实例方法:',GV_CHAR.
       " WRITE:/ GV_STATIC.  实例方法可以访问静态属性
      ENDMETHOD.
    
      METHOD WRITE_STATIC.
        WRITE:/ '静态方法:', GV_STATIC.
    *    WRITE:/ '访问实例方法',GV_CHAR.               "在静态方法中不可以访问实例组件
      ENDMETHOD.
    
      METHOD WRITE_INSTANGE.  "实例
        WRITE:/ '实例方法',GV_STATIC.
      ENDMETHOD.
    
      METHOD SET_VALUE.
        GV_CHANGE = I_VALUE.
      ENDMETHOD.
    
      METHOD GET_VALUE.
        E_VALUE = GV_CHANGE.
      ENDMETHOD.
    
      METHOD CON_VALUE.
        CONCATENATE I_VALUE1 I_VALUE2 I_VALUE3 INTO GV_CONCATENATE. "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. "CONCATENATE:连接
        IF SY-SUBRC = 0.
          E_CONCAT = GV_CONCATENATE.
        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 = C_PI * I_R ** 2.
    *  ENDMETHOD.
    
    *将圆周率作为参数传入
      METHOD GET_ROUND_02.
          E_ROUND = I_PI * I_R ** 2.   "计算面积
      ENDMETHOD.
    
      METHOD CONSTRUCTOR.
        WRITE:/ '执行了构造器函数'.   "执行结果返回两个语句,是因为声明了两个OBJECT 对象
        WRITE:/ I_CHAR.
      ENDMETHOD.
    
      METHOD WRITE_INTERFACE.
        WRITE:/ '接口中的方法'.
      ENDMETHOD.
    
      METHOD GET_DATA.
        SELECT SINGLE *
          FROM ZSCHOOL_LPJ_01
          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.
    
    *&---------------------------------------------------------------------*
    *&  继承LCL_COMPT   INHERITING:继承
    *&---------------------------------------------------------------------*
    CLASS LCL_SUB DEFINITION INHERITING FROM LCL_COMPT.
      PUBLIC SECTION.
      "声明一个方法
      METHODS WRITE_SUPER.
    
      METHODS GET_ROUND_02 REDEFINITION.  "针对父类中存在的方法;对父类方法GET_ROUND_02进行重定义
    
      METHODS CALCULATE_CIRCLE IMPORTING I_R TYPE GTY_P02.
    ENDCLASS.
    
    CLASS LCL_SUB IMPLEMENTATION.
      "使用声明的方法
      METHOD WRITE_SUPER.
        WRITE:/ 'PUBLIC SECTION.',GV_CHAR.   "共有部分
        WRITE:/ 'PROTECT SECTION',GV_SUBER.  "保护部分
        "WRITE:/ 'PRIVATE SECTION',GV_STATIC_PRI.  "私有部分  不能被继承类访问,只能内部访问
      ENDMETHOD.
    
      METHOD GET_ROUND_02.
    "   父类中 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 GET_ROUND_02
          EXPORTING
            I_R = I_R
            I_PI = '3.14'
          RECEIVING
          E_ROUND = LV_SPACE.
        WRITE:/ LV_SPACE.
    
    * 子类中GET_ROUND_02计算周长
        CALL METHOD ME->GET_ROUND_02  "ME指定当前类(子类)中的方法
          EXPORTING
            I_R = I_R
            I_PI = '3.14'
          RECEIVING
          E_ROUND = LV_SPACE.
    
        WRITE:/ LV_SPACE.
      ENDMETHOD.
    ENDCLASS.
    
    *&---------------------------------------------------------------------*
    *&   定义一个抽象类
    *&---------------------------------------------------------------------*
    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.
    
    *&---------------------------------------------------------------------*
    *&  事件接收器
    *&---------------------------------------------------------------------*
    CLASS LCL_HEANDLER 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_HEANDLER IMPLEMENTATION.
      METHOD WRITE_DATA.
        WRITE:/ PS_SCHOOL-ZSCHOOL,PS_SCHOOL-ZADDRESS.
      ENDMETHOD.
    
      METHOD WRITE_INT.
        WRITE:/ P_INT.
      ENDMETHOD.
    
    ENDCLASS.
    
    
    
    *  声明一个对象
    DATA LCL_OBJECT   TYPE REF TO LCL_COMPT.          "参照LCL_COMPT类声明具体的OBJECT对象。
    DATA LCL_OBJECT_2 TYPE REF TO LCL_COMPT.          "参照LCL_COMPT类声明具体的OBJECT对象。
    
    START-OF-SELECTION.
    *  创建对象的过程就是实例化;创建的对象就是实例
      CREATE OBJECT LCL_OBJECT
          EXPORTING
            I_CHAR = '实例1'.   "实例化
      CREATE OBJECT LCL_OBJECT_2
          EXPORTING
            I_CHAR = '实例2'.   "实例化
    
    *  实例属性,在在不同的实例之间独立
      WRITE:/ '访问实例属性:',LCL_OBJECT->GV_CHAR.  "访问实例属性      实例方法和实例属性通过实例来调用
      LCL_OBJECT->GV_CHAR = '更换char的值'.          "修改实例1
    
      CALL METHOD LCL_OBJECT->WRITE_CHAR.            "实例1的值
      CALL METHOD LCL_OBJECT_2->WRITE_CHAR.          "实例2的值
    
    *  静态属性,不依附于实例
      WRITE:/ '访问静态属性:',LCL_COMPT=>GV_STATIC. "访问静态属性
      LCL_COMPT=>GV_STATIC = '更换静态属性的值'.
      CALL METHOD LCL_COMPT=>WRITE_STATIC.           "静态方法
    
    *&---------------------------------------------------------------------*
    *& 带有参数的方法的调用 SET_VALUE和GET_VALUE是实例方法,通过实例调用
    *&---------------------------------------------------------------------*
      DATA: GV_DATA TYPE LCL_OBJECT->CTY_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.
    
    *  method中的参数(区分exporting和returning的区别)
     DATA: GV_SUBRC TYPE C.
      CALL METHOD LCL_OBJECT->CON_VALUE
        EXPORTING
    *      I_VALUE1 = 'BJ;'
          I_VALUE2 = 'CHIA;'
          I_VALUE3 = 'GREAT'
        IMPORTING
          E_CONCAT = GV_DATA
          E_SUBRC = GV_SUBRC.
      WRITE:/ GV_DATA ,GV_SUBRC.
    
      CALL METHOD LCL_OBJECT->RET_VALUE
        EXPORTING
          I_VALUE1 = 'BJ;'
          I_VALUE2 = 'CHIA;'
          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.
    *CALL METHOD LCL_OBJECT->GET_ROUND_02
    *  EXPORTING
    *    I_R  = P_R
    *  RECEIVING
    *    E_ROUND = GV_ROUND.
    
    *或者下面的方法 圆周率作为常量
    *GV_ROUND = LCL_OBJECT->GET_ROUND_02( P_R ).   "注意括号和参数之间的空格
    
    *圆周率作为参数传入
    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 = '子类实例化'.   "因为子类继承了父类,并且父类中有构造方法且指明传输参数,所以在这块的声明处 要对CONSTRUCTOR的参数 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_HEANDLER. "声明一个对象
      DATA: EVENT_HANDLER_2 TYPE REF TO LCL_HEANDLER.
      CREATE OBJECT EVENT_HANDLER.  "实例化
      CREATE OBJECT EVENT_HANDLER_2.
    
    * 注册 :SET HANDLER 实例2—>方法  for 实例1
      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.
    
      SET HANDLER EVENT_HANDLER->WRITE_DATA FOR OBJECT_SUB.
      SET HANDLER EVENT_HANDLER->WRITE_INT  FOR LCL_OBJECT.
    
    *&---------------------------------------------------------------------*
    *&  此处打断点,查看事件的过程
    *&---------------------------------------------------------------------*
      CALL METHOD LCL_OBJECT->GET_DATA
        EXPORTING
          P_SCHOOL = '欧亚学院'.
    
      CALL METHOD LCL_OBJECT_2->GET_DATA
        EXPORTING
          P_SCHOOL = '欧亚学院'.
    
      WRITE:/ '调用子类中的方法:'.
      CALL METHOD OBJECT_SUB->GET_DATA
        EXPORTING
          P_SCHOOL = '欧亚学院'.
    
      DO 50 TIMES.
        CALL METHOD LCL_OBJECT->ADD_DATA.
      ENDDO.
    *&--------------------------------------------------------------------*
    *&--------------------------------------------------------------------*
    *&  例子:
    *&  需求:
    *&    设置一个数字从1 循环到50,当他是10的倍数的时候,触发事件,输出当前的值
    *&---------------------------------------------------------------------*
    

    相关文章

      网友评论

        本文标题:程序中声明的类练习

        本文链接:https://www.haomeiwen.com/subject/ypsklctx.html