Creating Instances of a Class

Objective

After completing this lesson, you will be able to create Instances of an ABAP Class

Instance Creation

You work with attributes like normal variables of the same type. Outside the class, however, the attribute name is not sufficient to identify the attribute unambiguously. To address a static attribute outside the class, first type the class name, then the static component selector (=>), and only then the attribute name. The static component selector is a double arrow made up of an equals sign and the greater than sign.

Hint

No blanks are allowed before or after the component selector.

For instance attributes the situation is even more complicated: In order to access an instance component, you need a reference variable.

A reference variable is a special kind of variable that you use to create, address, and manage an object. A reference variable is used to point at the instance of a class in the program memory. You declare reference variables using the DATA statement with the addition TYPE REF TO followed by the name of a class.

The initial value of a reference variable is called the NULL reference; the reference does not yet point anywhere.

To create a new instance of a class, you use the NEW operator. The example above, uses a NEW #( ) expression on the right hand side of a value assignment. The result of the expression is the memory address of the newly created instance. This reference is then stored in the reference variable on the left-hand side of the assignment.

You may have noticed that the name of the class that you want to instantiate does not appear anywhere in the expression. However, from the location of the NEW #( ) expression, the system already knows that the target variable connection has the type REF TO lcl_connection, and consequently it knows that it should create an instance of the class lcl_connection. The pound sign after the NEW operator means "use the type of the variable before the equals sign". (In more advanced scenarios, you can actually specify the name of the class in place of the pound sign).

Hint

There must be at least one blank between the brackets.

When you address a class for the first time (which could be accessing a static component or creating an instance of the class), the runtime system also loads the class definition into the program memory. This class definition contains all of the static attributes, which only exist once in the class instead of once for each instance.

You address static components using the class name and the static component selector. This does not work for instance components because you have to specify the instance you want to access.

To address an instance attribute outside the class, first type the reference variable, then the instance component selector (->), and only then the attribute name. The instance component selector is an arrow made up of a dash and the greater than sign.

Note

Unlike many other programming languages, ABAP uses different characters for instance component selector and static component selector.

One of the main characteristics of object oriented programming is the fact that you can create multiple instances of the same class. Each instance is created in a different place in the program memory and the values of instance attributes in one instance are independent from the values in other instances. But as the graphic illustrates, instances of the same class share the value for the static attributes.

If you assign one reference variable to another, the system copies the address of the object to which the first variable is pointing into the second reference variable. The result of this is that you have two reference variables that point to the same object.

You can use the same reference variable to create more than one instance of a class. Each time you use the NEW #( ) expression, the system creates a new instance of the class and places the address of the new instance into the reference variable. However, the address of the new instance overwrites the address of the previous instance.

In the example above, the address of lcl_connection (2) overwrites the address of lcl_connection (1). Consequently, there is no longer a reference variable in the program pointing to lcl_connection (1). When this happens to an instance, it can no longer be addressed from the program.

To prevent the program memory from becoming filled with objects that can no longer be addressed and eventually overflowing, the runtime system has a component called the garbage collector. The garbage collector is a program that runs periodically to look for and destroy objects to which no more references point. If during a program you delete the last reference to an object by overwriting it or using the CLEAR statement, the garbage collector will destroy the object on its next pass.

Note

At the end of a program, when all of the reference variables are freed, the garbage collector will destroy all of the instances to which they had pointed. You do not have to worry about resource management in the program yourself.

How to Create Instances of an ABAP Class

Instance Management in an Internal Table

One way in which you can keep objects alive is to place the references into an internal table. This is a technique that you may well want to use if you are creating a whole series of objects. It enables you to use a single reference variable to create lots of objects. Although the reference variable is overwritten with the address of the next object, the existing objects are safe because the internal table contains a reference to them. You therefore never delete the "last" reference to the objects.

How To Manage Instances in an Internal Table

Create and Manage Instances

In this exercise, you create and manage instances of your local class.

Template:

  • /LRN/CL_S4D400_CLS_LOCAL_CLASS (global Class)

Solution:

  • /LRN/CL_S4D400_CLS_INSTANCES (global Class)

Task 1: Copy Template (Optional)

Copy the template class. If you finished the previous exercise you can skip this task and continue editing your class ZCL_##_LOCAL_CLASS.

Steps

  1. Open the source code of global class/LRN/CL_S4D400_CLS_LOCAL_CLASS in the ABAP editor.

    1. In the Eclipse toolbar, choose Open ABAP Development Object. Alternatively, press Ctrl + Shift + A.

    2. Enter /LRN/CL_S4D400_CLS as search string.

    3. From the list of development objects choose /LRN/CL_S4D400_CLS_LOCAL_CLASS, then choose OK.

  2. Link the Project Explorer view with the editor.

    1. In the Project Explorer toolbar, find the Link with Editor button. If it is not yet pressed, choose it. As a result, the development object, that is open in the editor, should be highlighted in the Project Explorer.

  3. Copy class /LRN/CL_S4D400_CLS_LOCAL_CLASS to a class in your own package (suggested name: ZCL_##_INSTANCES, where ## stands for your group number).

    1. In the Project Explorer view, right-click class /LRN/CL_S4D400_CLS_LOCAL_CLASS to open the content menu.

    2. From the context menu, choose Duplicate ....

    3. Enter the name of your package in the Package field. In the Name field, enter the name ZCL_##_INSTANCES, where ## stands for your group number.

    4. Adjust the description and choose Next.

    5. Confirm the transport request and choose Finish.

Task 2: Create an Instance

In the main method of your global class, declare a reference variable and create an instance of your local class.

Steps

  1. In method if_oo_adt_classrun~main of your global class, declare a reference variable (suggested name: connection) and type it with your local class lcl_connection.

    1. Switch to the Global Class tab.

    2. Adjust the code as follows:

      Code Snippet
      1234567
      METHOD if_oo_adt_classrun~main. DATA connection TYPE REF TO lcl_connection. ENDMETHOD.
  2. Create an instance of the class and set the attributes carrier_id and connection_id (Suggested values: "LH" for attribute carrier_id and "0400" for attribute connection_id.

    1. Adjust the code as follows:

      Code Snippet
      12345678
      DATA connection TYPE REF TO lcl_connection. connection = new #( ). connection->carrier_id = 'LH'. connection->connection_id = '0400'.

      Hint

      After typing the component selector (->), press Strg + Space to choose the attribute names from a suggestion list.
  3. Activate the class and use the debugger to analyze step by step what happens.

    1. Press Ctrl + F3 to activate the class.

    2. Double-click the left-hand margin of the editor next to the line connection = new #( ).to set a break point.

    3. Press F9 to run the class.

    4. Double-click the word connection to display the content of reference variable connection.

    5. Press F5 to go one step further in the debugger. Check that the value of connection has changed.

    6. In the Variablesview, expand the branch connection to display the initial attributes of the class.

    7. Press F5 to go one step further in the debugger. Check that the value of carrier_id has changed.

    8. Press F5 again. Check that the value of Connection_ID has changed.

Task 3: Manage Several Instances

Create more instances of your local class and store the references to these instances in an internal table.

Steps

  1. In method if_oo_adt_classrun~main( ) of your global class, declare an internal table with the line type TYPE REF TO lcl_connection (suggested name: connections).

    1. Adjust the code as follows:

      Code Snippet
      123456789
      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'.
  2. After instantiating the class and setting the attributes, append the object reference to the internal table.

    1. Adjust the code as follows:

      Code Snippet
      123456789
      connection = NEW #( ). connection->carrier_id = 'LH'. connection->connection_id = '0400'. APPEND connection TO connections.
  3. Create two more instances of class lcl_connection, set their instance attributes to different values than in the first instance and append the references to the new instances to internal table connections. Use the same reference variable connection for all three instances.

    1. Adjust the code as follows:

      Code Snippet
      12345678910111213141516171819202122
      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.
  4. Activate the class and use the debugger to analyze step by step what happens.

    1. Press Ctrl + F3 to activate the class.

    2. Double-click the left-hand margin of the editor next to the first line connection = new #( ).to remove the break point.

    3. Double-click the left-hand margin of the editor next to the first line APPEND connection TO connections.to set a new break point.

    4. Press F9 to run the class.

    5. Double-click the word connection to display the content of reference variable connection.

    6. Double-click the word connections to display the content of internal table connections.

    7. Press F5 to go one step further in the debugger. Check that the content of connections has changed.

    8. In the Variables view, expand the branch connections to display content of the internal table.

    9. Press F5 several times until you reach the end of the program. While you do so, check the content of the internal table.

    10. Compare your code on tab Global Class to the following extract from the model solution:

      Code Snippet
      123456789101112131415161718192021222324252627282930313233343536
      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.

Log in to track your progress & complete quizzes