Defining Interfaces

Objective

After completing this lesson, you will be able to Define interfaces.

Interface Definition

Reasons to Use Interfaces

Interfaces allow you to define how a program will address one or more classes. In an interface, you can define methods, attributes, types, and constants, just as you would in a class. These components form a description of how a client program could interact with the corresponding objects. However, an interface cannot be instantiated, and does not contain any implementations of its methods. To make the concept work, we also need one or more classes that implement the interface. This means that they include the interface in their own class declaration and the components that are declared in the interface become part of the class itself. If the interface contains method declarations, the class that implements the interface must also provide an implementation of that method.

Interfaces have two important uses:

Providing a unified approach to different classes: If you have classes that are not related by inheritance, but that should still provide common services to their users, you can define the common services in an interface. This ensures that each class provides a method with the same name and the same signature to perform a particular task. Programs that use the classes then have a single way to call particular functions regardless of which class they are actually addressing.

Providing a simplified approach to a complex class: As you will see later on, interfaces provide a restricted view of an object. This enables you to expose a particular set of methods to a program that will use a particular class on the basis of the functions that the program actually requires.

Watch this example to know how an interface works.

Interface Definition

The definition of an interface is very similar to the definition section of a class. However, since an interface does not have an implementation, there is no DEFINITION addition in the INTERFACE statement. The second major difference is that there are no visibility sections in an interface, as all components of an interface are public. Interfaces are useful because of their interaction with other classes, so having non-public components would make no sense.

In the interface definition, you can use types, attributes, constants, and methods, and both instance and static components are allowed. Remember that interface methods have a definition, but no implementation. This will be supplied by the implementing class.

In many ways, interfaces are similar to abstract super classes. They provide a useful technique for cases in which you need to define common components for classes without there being a case for inheritance, in other words, there is no clear "is a" relationship.

Implementing the Interface

To implement an interface in a class, you use the INTERFACES statement. As all components of the interface are public and you cannot change the visibility of an existing component, you must include the interface in the public section of the class.

As soon as you have written the INTERFACES statement, your program is syntactically incorrect. This is because the interface contains a method that you have not yet implemented. You can use a quick fix (Ctrl + 1) to add the method implementation to your class.

When you declare in interface in a class, you must implement all of its methods.

In the implementation of your class, you must implement all of the methods that are declared in the interface. When you name the method in the implementation, you must use the fully-qualified name, which consists of the interface name and the method name joined by a tilde. This is because there is no guarantee that the method name by itself is unambiguous; remember that component names must only be unique in the class or interface in which they are declared. Consequently, a class could declare a method called get_partner_attributes as well as the interface lif_partner.

Try It Out: Interface Definition

  1. Create a new class that implements the interface IF_OO_ADT_CLASSRUN.
  2. Switch to the Local Types tab and copy the following code snippet into the editor:
    Code Snippet
    Copy code
    Switch to dark mode
    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
    INTERFACE lif_partner. METHODS get_partner_attributes. ENDINTERFACE. CLASS lcl_travel_Agency DEFINITION. PUBLIC SECTION. ENDCLASS. CLASS lcl_airline DEFINITION. PUBLIC SECTION. INTERFACES lif_Partner. TYPES: BEGIN OF ts_detail, name TYPE string, value TYPE string, END OF ts_detail, tt_Details TYPE SORTED TABLE OF ts_detail WITH UNIQUE KEY name. METHODS get_details RETURNING VALUE(rt_details) TYPE tt_details. ENDCLASS. CLASS lcl_car_Rental DEFINITION. PUBLIC SECTION. interfaces lif_Partner. TYPES: BEGIN OF ts_info, name TYPE c LENGTH 20, value TYPE c LENGTH 20, END OF ts_info, tt_Info TYPE SORTED TABLE OF ts_info WITH UNIQUE KEY name. METHODS get_information RETURNING VALUE(rt_details) TYPE tt_info. ENDCLASS. CLASS lcl_airline IMPLEMENTATION. METHOD get_details. ENDMETHOD. METHOD lif_partner~get_partner_attributes. ENDMETHOD. ENDCLASS. CLASS lcl_car_rental IMPLEMENTATION. METHOD get_information. ENDMETHOD. METHOD lif_partner~get_partner_attributes. ENDMETHOD. ENDCLASS.
  3. Press Ctrl + F3 to activate the class.
  4. Familiarize yourself with the code.

    Note

    There is no executable code in this example.

Define and Implement an Interface

You realize that method GET_OUTPUT in local class LCL_CARRIER and method GET_DESCRIPTION in local class LCL_FLIGHT are very similar. To harmonize the definition, you introduce an Interface and implement it in both classes.

Template:

  • /LRN/CL_S4D401_OOS_INH_USAGE (Global Class)

Solution:

  • /LRN/CL_S4D401_OOS_INTERFACE (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_##_SOLUTION.

Steps

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

    1. In the Project Explorer view, right-click class /LRN/CL_S4D401_OOS_IN_USAGE to open the context 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_##_SOLUTION, where ## stands for your group number.

    4. Adjust the description and choose Next.

    5. Confirm the transport request and choose Finish.

  2. Activate the copy.

    1. Press Ctrl + F3 to activate the class.

Task 2: Define the Interface

Define a local interface (suggested name: LIF_OUTPUT) and implement it in local classes LCL_FLIGHT and LCL_CARRIER.

Note

Leave the interface empty for now. We will add interface components in the next task.

Steps

  1. In your global class, navigate to the definition of local class LCL_FLIGHT.

    1. For example, choose the class name on the Outline view.

  2. In the public section, add a statement that declares the implementation of the not yet existing interface.

    1. Adjust the code as follows:

      Code Snippet
      Copy code
      Switch to dark mode
      12345
      CLASS lcl_flight DEFINITION. PUBLIC SECTION.
  3. Use a quick fix to create the interface as a local interface.

    1. In the INTERFACES statement, place the cursor on lif_output and press Ctrl + 1 to invoke the quick fix.

    2. Alternatively, you can choose the error icon with the light bulb on the left-hand side of the code row.

    3. From the list of available quick fixes, choose Create local interface lif_output.

  4. Implement the new interface also in local class LCL_CARRIER.

    1. Navigate to the definition of local class LCL_CARRIER.

    2. Adjust the code as follows:

      Code Snippet
      Copy code
      Switch to dark mode
      12345
      CLASS lcl_carrier DEFINITION. PUBLIC SECTION.

Task 3: Implement Interface Methods

Move the definition of instance method GET_OUTPUT from the class to the interface. Then implement the interface in local class LCL_FLIGHT, where you forward the request to method GET_DESCRIPTION.

Steps

  1. Use a quick fix to move (pull-up) method GET_OUTPUT from local class LCL_CARRIER to the local interface.

    Note

    Ignore the warning that the method refers to other components of the class.
    1. In local class LCL_CARRIER navigate to the definition of instance method GET_OUTPUT.

    2. In the METHODS statement, place the cursor on get_output and press Ctrl + 1 to invoke the quick fix.

    3. From the list of available quick fixes, choose Pull-Up get_output to interface lif_output.

    4. Read the warning carefully, but then choose Proceed to ignore it.

  2. Analyze the new syntax error on the Problems view.

    1. Find the Problems view in the tab strip below the editor.

  3. Use the same quick fix to move (pull-up) the types TT_OUTPUT and T_OUTPUT from local class LCL_CARRIER to the interface.

    1. In local class LCL_CARRIER navigate to the definition of types, TT_OUTPUT.

    2. In the TYPES statement, place the cursor on TT_output and press Ctrl + 1 to invoke the quick fix.

    3. From the list of available quick fixes, choose Pull-Up tt_output to interface lif_output.

    4. Choose Proceed to ignore the warning related to type, T_OUTPUT.

    5. Repeat the previous steps to pull-up type T_OUTPUT to the interface.

  4. If necessary, adjust the sequence of type TT_OUTPUT and T_OUTPUT in the interface definition.

    1. The interface definition should look like this:

      Code Snippet
      Copy code
      Switch to dark mode
      12345
      INTERFACE lif_output. ENDINTERFACE.
  5. Use a quick fix to add the missing implementation of interface method GET_OUTPUT in local class LCL_FLIGHT.

    1. Navigate to the definition of local class LCL_FLIGHT.

    2. In the INTERFACES statement, place the cursor on lif_output and press Ctrl + 1.

    3. Alternatively, choose the error icon with the light bulb on the left-had side of the code row.

    4. From the list of quick fixes, choose Add implementation for get_output.

  6. In method lif_output~get_output, implement a call of instance method get_description and store the result in returning parameter r_result.

    1. Adjust the code as follows:

      Code Snippet
      Copy code
      Switch to dark mode
      1234
      METHOD lif_output~get_output. ENDMETHOD.
  7. Activate and test your global class as console app.

    1. Press Ctrl + F3.

    2. Press F9.

Log in to track your progress & complete quizzes