创建类的实例
学习目标
创建 ABAP 类的实例。
实例创建

您使用相同类型的属性,如普通变量。但是,在类之外,属性名称不足以明确标识属性。要处理类之外的静态属性,首先键入类名称,然后键入静态组件选择器 (=>),然后是属性名称。静态部件选择器是一个双箭头,由等号和大于号组成。
提示
在部件选择器之前或之后不允许使用空格。

对于实例属性,情况更加复杂:要访问实例组件,您需要参考变量。
参考变量是用于创建、寻址和管理对象的特殊类型的变量。参考变量用于指向程序内存中的类实例。使用 DATA 语句声明参考变量,其中附加项 TYPE REF TO 后跟类名称。
引用变量的初始值称为 NULL 引用;引用尚未指向任何位置。

要创建类的新实例,请使用 NEW 运算符。上面的示例使用值赋值右侧的 NEW #( ) 表达式。表达式的结果是新创建 实例的内存地址。然后将此参考存储在分配左侧的参考变量中。
您可能已经注意到,要实例化的类名不会出现在表达式中的任何位置。但是,从 NEW #( ) 表达式的位置,系统已经知道目标变量连接的类型为 REF TO lcl_connection,因此知道它应该创建类 lcl_connection 的实例。NEW 运算符后的井号表示"在等号前使用变量的类型"。(在更高级的场景中,您可以实际指定类名称代替井号)。
提示
括号中必须至少有一个空格。
首次寻址类(可以是访问静态组件或创建类的实例)时,运行时系统也会将类定义加载到程序内存中。此类定义包含所有静态属性,这些属性在类中仅存在一次,而不是针对每个实例存在一次。

使用类名和静态组件选择器处理静态组件。这不适用于实例组件,因为您必须指定要访问的实例。
要处理类之外的实例属性,首先键入参考变量,然后输入实例组件选择器 (->),然后是属性名称。实例组件选择器是由短划线和大于号组成的箭头。
注意
与许多其他编程语言不同,ABAP 对实例组件选择器和静态组件选择器使用不同的字符。

面向对象的编程的主要特征之一是,您可以创建同一类的多个实例。每个实例在程序内存的不同位置创建,并且一个实例中实例属性的值与其他实例中的值无关。但如图所示,同一类的实例共享静态属性的值。

如果将一个参考变量分配给另一个参考变量,系统会将第一个变量指向的对象的地址复制到第二个参考变量。其结果是您有两个指向同一对象的参考变量。

您可以使用相同的参考变量来创建类的多个实例。每次使用 NEW #() 表达式时,系统都会创建类的新实例并将新实例的地址放入参考变量中。但是,新实例的地址将覆盖先前实例的地址。
在上面的示例中,lcl_connection (2) 的地址覆盖 lcl_connection (1) 的地址。因此,程序中不再存在指向 lcl_connection (1) 的参考变量。当实例发生这种情况时,将无法再通过程序对其进行寻址。
为防止程序内存填充了无法再寻址并最终溢出的对象,运行时系统具有称为垃圾收集器的组件。垃圾收集器是一个定期运行的程序,用于查找和销毁不再有参考点的对象。如果在程序期间通过覆盖对象或使用 CLEAR 语句删除对象的最后参考,则垃圾收集器将在下次传输时销毁该对象。
注意
程序结束时,当释放所有参考变量时,垃圾收集器将销毁它们指向的所有实例。您不必担心程序中的资源管理。
如何创建 ABAP 类的实例
演示:观看演示(SAP 官方交互式练习)
内部表中的实例管理

一种可以保持对象处于活动状态的方式,是将参考置于内部表中。如果要创建整个对象系列,则最好使用此技术。它使您能够使用单个参考变量创建大量对象。尽管引用变量被下一个对象的地址覆盖,但现有对象是安全的,因为内部表包含对它们的引用。因此,从不删除对象的"最后一个"参考。
如何管理内部表中的实例
演示:观看演示(SAP 官方交互式练习)
创建和管理实例
在本练习中,您将创建和管理本地类的实例。
模板:
/LRN/CL_S4D400_CLS_LOCAL_CLASS(全局类)
解决方案:
/LRN/CL_S4D400_CLS_INSTANCES(全局类)
任务 1: 复制模板(可选)
复制模板类。如果您已完成上一练习,则可以跳过此任务并继续编辑类 ZCL_##_LOCAL_CLASS。
步骤
在 ABAP 编辑器中打开全局类
/LRN/CL_S4D400_CLS_LOCAL_CLASS的源代码。在 Eclipse 工具栏中,选择打开 ABAP 开发对象。或者,按
Ctrl + Shift + A。输入
/LRN/CL_S4D400_CLS作为搜索字符串。从开发对象列表中选择 /LRN/CL_S4D400_CLS_LOCAL_CLASS,然后选择确定。
将项目浏览器视图与编辑器链接。
在项目浏览器工具栏中,找到与编辑器链接按钮。如果尚未按下,请选择它。因此,应在项目浏览器中突出显示在编辑器中打开的开发对象。
将类
/LRN/CL_S4D400_CLS_LOCAL_CLASS复制到您自己的包中的类(建议名称:ZCL_##_INSTANCES,其中 ## 代表组编号)。在项目浏览器视图中,右键单击类
/LRN/CL_S4D400_CLS_LOCAL_CLASS以打开内容菜单。从上下文菜单中,选择复制 ....
在包字段中输入包的名称。在名称字段中,输入名称
ZCL_##_INSTANCES,其中 ## 代表组编号。调整描述,然后选择下一步。
确认传输请求并选择完成。
任务 2: 创建 实例
在全局类**的主**方法中,声明参考变量并创建局部类的实例。
步骤
在全局类的方法
if_oo_adt_classrun~main中,声明一个参考变量(建议名称:connection),然后使用局部类lcl_connection键入该变量。切换到全局类标签。
如下调整代码:
METHOD if_oo_adt_classrun~main.
DATA connection TYPE REF TO lcl_connection.
ENDMETHOD.
创建 类的实例并设置属性
carrier_id和connection_id(建议值:LH 表示属性carrier_id,0400 表示属性connection_id)。如下调整代码:
DATA connection TYPE REF TO lcl_connection.
connection = new #( ).
connection->carrier_id = 'LH'.
connection->connection_id = '0400'.
提示
键入组件选择器 (->) 后,按 Strg + 空格从建议列表中选择属性名称。
激活类并使用调试器逐步分析发生的情况。
按
Ctrl + F3激活类。双击行
connection = new #( ).旁的编辑器左边距以设置断点。按
F9键运行类。双击单词
connection以显示参考变量**连接的**内容。按
F5在调试器中进一步执行。检查**连接** 的值是否已更改。在变量视图中,展开分支**
连接**以显示类的初始属性。按
F5在调试器中进一步执行。检查carrier_id的值是否已更改。再次按 F5。检查
Connection_ID的值是否已更改。
任务 3: 管理多个实例
创建本地类的更多实例,并将对这些实例的引用存储在内部表中。
步骤
在全局类的方法
if_oo_adt_classrun~main()中,声明行类型为REF TO lcl_connection的内部表(建议名称:连接)。如下调整代码:
DATA connection TYPE REF TO lcl_connection.
DATA connections TYPE TABLE OF REF TO lcl_connection.
connection = new #( ).
connection->carrier_id = 'LH'.
connection->connection_id = '0400'.
实例化 类并设置属性后,将对象引用附加到内部表。
如下调整代码:
connection = NEW #( ).
connection->carrier_id = 'LH'.
connection->connection_id = '0400'.
APPEND connection TO connections.
再创建两个类
lcl_connection的实例,将其实例属性设置为与第一个实例不同的值,并将新实例的引用附加到内部表**连接。对所有三个实例使用相同的参考变量连接**。如下调整代码:
connection = NEW #( ).
connection->carrier_id = 'LH'.
connection->connection_id = '0400'.
APPEND connection TO connections.
connection = NEW #( ).
connection->carrier_id = 'AA'.
connection->connection_id = '0017'.
APPEND connection TO connections.
connection = NEW #( ).
connection->carrier_id = 'SQ'.
connection->connection_id = '0001'.
APPEND connection TO connections.
激活类并使用调试器逐步分析发生的情况。
按
Ctrl + F3激活类。双击第一行
connection = new #( ).旁的编辑器左边距以移除断点。双击第一行
APPEND connection TO connections.旁的编辑器左侧边距,设置新的断点。按
F9键运行类。双击单词
connection以显示参考变量**连接的**内容。双击单词
connections以显示内部表**连接的**内容。按
F5在调试器中进一步执行。检查**连接**的内容是否已更改。在变量视图中,展开分支**
连接**以显示内部表的内容。多次按
F5,直到程序结束。执行此操作时,请检查内部表的内容。将全局类标签上的代码与模型解决方案的以下提取内容进行比较:
METHOD if_oo_adt_classrun~main.
DATA connection TYPE REF TO lcl_connection.
DATA connections TYPE TABLE OF REF TO lcl_connection.
* First Instance
**********************************************************************
connection = NEW #( ).
connection->carrier_id = 'LH'.
connection->connection_id = '0400'.
APPEND connection TO connections.
* Second Instance
**********************************************************************
connection = NEW #( ).
connection->carrier_id = 'AA'.
connection->connection_id = '0017'.
APPEND connection TO connections.
* Third Instance
**********************************************************************
connection = NEW #( ).
connection->carrier_id = 'SQ'.
connection->connection_id = '0001'.
APPEND connection TO connections.
ENDMETHOD.