从SAP R/3 4.0版本开始,ABAP就引入了面向对象的开发概念。
ABAP语言的发展
- 宏编译器
- ABAP语言出现-面向过程
- ABAP语言-面向对象(Object-oriented)
• ABAP对象是ABAP的扩展,集合了Java, C++, Smalltalk等语言的特点,和原来的ABAP无缝集成
面向对象解决方法中,重点放在了对象结构化或抽象化
- 属性(Attributes):对象的属性及特征
- 方法(Method):定义对象的行为
类的优点
- 可以重复利用代码(传统ABAP->重用部分)
- 可以封装数据
面向对象开发特点
1.抽象(Abstraction)
- 实现客观世界实体的模块化
2.封装(Encapsulation)
- 就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏
3.继承(Inheritance)
- 它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展
4.多态(Polymorphism)
- 允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说:允许将子类类型的指针赋值给父类类型的指针。
类和对象
什么是对象?
- 类=>类型,对象=>个体
- 要使用所需功能的对象,首先要经过根据类定义对象的过程
- 根据类创建对象的过程成为实例化,根据类创建的对象为实例 (Instance)
CLASS:类是创建对象的模板
OBJECT:对象是指商品/物体/对象/目的,是类的实例
类的区分:
- 全局类(Global):使用事务代码SE24
存储在类池中(Class Libraryin the Repository)
所有ABAP程序都可以对其进行访问 - 本地类(Local)
在程序中定义
只有该程序可以使用
类的创建
定义类的构成项目(属性、方法、事件)
CLASS<class>DEFINITION.
- 要素声明
- 所有项目都需要定义在三个访问区域之一中
ENDCLASS.
三个访间区域
-
Public Section.公有部分
内部可见,外部可见
PUBLIC部分的组件,构成类与用户的接口 -
Protected Section.保护部分
内部可见,继承可见,外部不可见
PROTECTED部分的组件,构成继承类之间的接口 -
Private Section.私有部分
内部可见,继承不可见,外部不可见
实现类的方法
CLASS<class>IMPLEMENTATION.
...
ENDCLASS.
CLASS构成要素
构成要素的分类
- 实例组件(Instance-specific component)
1.参照类创建对象时,内存中存在的项目,每次创建对象时都会被初始化。各个类的对象中都存在
2.声明方式:
属性:DATA:
方法:METHODS
访问:OBJECT->COMP - 静态组件(Static component)
1.遇到创建类的语句(CREATEOBIECT)开始,直到程序结束都存储于内存中,是依赖类存在的项目。即使不创建对象,若已存在与内存中即可以直接使用。
2.声明方式:
属性:CLASS-DATA:
方法:CLASS-METHODS
访问:CLASS=>COMP - 类的所有要素在声明部分实现(ClassDefinition)
属性(Attributes):可以拥有ABAP所有数据类型的类内部数据字段,对象状态由属性决定。DATA/CONSTANTS
方法(Method):用来定义决定对象行为的类内部执行步骤,可以访问类的所有属性,切可通过方法修改对象的内容,另外,方法提供传入传出参数,便于用户交互
事件(Event):事件是没有继承关系的类之间可以互相调用彼此方法的特殊方法
*事件声明
EVENTS evt EXPORTING .. VALUE(e1 e2) TYPE type
*调用事件(Trigger)
RAISE EVENT evt EXPORTING e1 =f1 e2 =f2 ..
*Event Handler声明
METHODS meth FOR EVENT evt OF cif IMPORTING e1 e2
*Event Handler注册/登陆
SET HANDLER h1 h2 [FOR] ..
对象
对象指的是类的实例,每个对象都有自己固有的属性,
一个类可以创建多个对象。
在ABAP程序中要访问对象,需要使用参照对象(0bjectReference),参照对象始终存在于参照对象变量中
DATA obj TYPE REF TO class.
方法
- 方法定义的基本语法
METHOD<meth>
IMPORTING ... <i1>TYPE <type> ....
EXPORTING... <e1>TYPE <type> ..
CHANGING ... <c1>TYPE <type> ...
EXCEPTIONS ... X1...
CALLMETHOD [oref->|class=>]meth
EXPORTING ...i1 = f1...
RECEIVING R = h.
- IMPORT/EXPORT:数据输入/输出接口,接口参数可以参考单个变量,结构,或者内表
- CHANGING:同时作为输入输出接口,接口参数可以参考单个变量,结构,或者内表
- RETURNING:返回类传递数值。该定义不能和CHANGING/EXPORTING同时使用
- EXCEPTIONS:返回执行中所出现的错误
- 类函数可以拥有多个输入参数,但只能有一个输出参数。类的输出接口参数必须与类函数中所定义类型保持一致
- 当方法没有输出参数(EXPORTING)的时候可以通过以下方式调用:
CALL METHOD meth().“没有输入参数
CALL METHOD meth(a).“一个输入
CALL METHOD meth( f1 =a1.....fn=an).“N个输入
构造方法
- 构造方法:
1.在实例化对象时,自动完成对象的初始化,并且这个对象是空的。
2.如果希望每一个对象都为其初始化某些特征,需要用到构造方法。
3.没有返回数据类型,功能是在实例化类时完成一些初始化工作
4.每个类只能有一个构造方法,在CREATEOBJECT语句中自动调用构造方法
- 使用METHODS CONSTRUCTOR定义
- 或使用CLASS-METHODS CLASS CONSTRUCTOR定义
- 什么时候使用构造方法
1.需要分配(外部)资源
2.需要初始化一些不能用DATA语句的VALUE指定的属性值
3.需要修改静态属性
4.通常不能显式的调用构造器
类的继承
-
类的继承?
继承的本质是代码重用,当要构造一个新类时,无需从零开始,可以参考一个已有类,在其基础上建立一个新类
参考类:基类/父类。新建类:派生类/子类
派生类可以继承基类所有的属性和方法,并可以在此基础上添加新的特性CLASS<subclass>DEFINITION INHERITING FROM<superclass>
-
多态性类继承的实现
由于每个派生类的属性不同,相同的基类对象在不同的派生类中需要以不同的方式来表现,因此提供多态的概念。
在派生类中定义和基类相同的接口,但是可以使用不同的代码来实现。
METHOD <meth> REDEFINITION.
*在派生类中使用基类的方法,使用SUPER:
CALL METHOD SUPER-><meth>.
重载方法,使用ME:
CALL METHOD ME-><meth>.
抽象类
- 抽象类
含有一个或多个方法的类,称为抽象类
抽象类不能使用CREATE OBJECT语句来创建实例对象
仅包含没有具体实现的方法
CLASS<class>DEFINITION ABSTRACT.
...
ENDCLASS.
-
抽象方法
仅包含方法定义,但没有具体实现的方法,需要通过派生类来实现METHODS<meth>ABSTRACT.
最终类
最终类和最终方法,都是不可继承的
-防止由于设计中多级别派生造成类造成的语法和语义的冲突
CLASS<class> DEFINITION FINAL.
...
ENDCLASS.
METHODS <meth> FINAL.
接口
- 接口(INTERFACE)
和抽象类相似,定义了一些未实现的属性和方法,所有继承它的类都继承这些成员不需要方法实现,不能直接实例化
接口所有成员都是抽象的
接口成员一般是公有的
接口中不能含有构造方法
INTERFACE <intf>
DATA ...
METHOD ...
ENDINTERFACE
CLASS <class> DEFINITION
PUBLIC SECTION .
INTERFACE: int1, int2
ENDCLASS.
- 静态成员访问时,通过接口引用访问 intf=>const
- 其他成员,可以通过实现该接口的类本身或者类引用进行访问
class=>intf~attr.
CAll METHOD class=>intf~meth .
- 直接调用接口方法,必须使用循环
- 别名:ALIASES alias FOR intf~com1.
接口的申明
"定义接口
INTERFACE INTER.
METHODS WRITE_INTER .
ENDINTERFACE.
接口需要在类中使用
接口方法重定义
调用接口
*接口中的方法的调用
CALL METHOD LCL_OBJECT->WRITE_INTERFACE.
事件
1.事件(EVENT)
- 用于捕获某类对象状态的改变来触发事件的方法,并进行处理
2.定义:可以在类或接口中进行声明
EVENTS|CLASS-EVENTS evt
EXPORTING ... VALUE(P1)TYPE type|LIKE f[OPTIONAL|DEFAULT g] ..
- 实例事件中包含一个隐含参数SENDER,该参数的类型为触发事件的类或接口对象引用
3.触发:一个实例事件可以被类中的任意方法触发,静态事件则可以被静态方
法触发
RAISE EVENT evt EXPORTING p1 = f1 ... pn = fn
4.事件处理:事件需要通过触发其声明代码中所定义的方法才能处理相关事务。
METHODS|CLASS-METHODS
meth FOR EVENT evt OF cif IMPORTING ...ei...
*为相关事件注册方法
SET HANDLER ... hi... [FOR] ...
5.事件类型分为4种
- 定义在类中的:实例事件,静态事件
- 定义在接口中的:实例事件,静态事件
对于实例事件,注册语句必须使用FOR指定注册对象
...FOR ref.
* 注册所有可以触发该事件的实例,包括尚未被创建的实例
...FOR ALL INSTANCES
注册静态事件,不需加FOR后缀,自动应用于整个类
当程序执行到RAISE EVENT语句后,所有已注册的处理方法都将在下一个语句之前被处理。处理方法按照其在系统内部注册的顺序被执行。为避免无限循环,目前事件处理最多不能超过64级嵌套