文章目录
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.