ABAP开发

程序中声明的类练习

2019-07-24  本文已影响0人  扇动蝴蝶的翅膀
*&---------------------------------------------------------------------*
*& 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的倍数的时候,触发事件,输出当前的值
*&---------------------------------------------------------------------*
上一篇下一篇

猜你喜欢

热点阅读