Showing posts with label Object Oriented ABAP - Interface. Show all posts
Showing posts with label Object Oriented ABAP - Interface. Show all posts

Encapsulation by Interface

Encapsulation by Interface

Encapsulation means one attribute and method can be modified in different classes. Hence data and method can have different form and logic and that can be hidden to separate class. 

Interface is used when we need to create one method with different functionality in different classes. Here the name of the method needs not to be changed. The same method will have to be implemented in different class implementations.

The following program contains an Interface it. There we have declared attribute and a method like mit. Now we have defined two classes like cls1 and cls2. So we have to implement the method mit in both of the class implementation. We have implemented the method mit differently in different class. Now in the start of selection we create two objects obj1 and obj2 for two classes. Next we call the method by different objects and we are getting the function declared in separate class.


*&---------------------------------------------------------------------*
*& Report  ZSR_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zsr_test.

*----------------------------------------------------------------------*
*       INTERFACE it
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
INTERFACE it.
  DATA v_txt TYPE char50.
  METHODS mit.
ENDINTERFACE.                    "it

*----------------------------------------------------------------------*
*       CLASS cls1 DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls1 DEFINITION.
  PUBLIC SECTION.
    INTERFACES it.
ENDCLASS.                    "cls1 DEFINITION

*----------------------------------------------------------------------*
*       CLASS cls2 DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls2 DEFINITION.
  PUBLIC SECTION.
    INTERFACES it.
ENDCLASS.                    "cls2 DEFINITION

*----------------------------------------------------------------------*
*       CLASS cls1 IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls1 IMPLEMENTATION.
  METHOD it~mit.
    it~v_txt = 'Class One Interface Method'.
    WRITE / it~v_txt.
  ENDMETHOD.                    "it~mit
ENDCLASS.                    "cls1 IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS cls2 IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls2 IMPLEMENTATION.
  METHOD it~mit.
    it~v_txt = 'Class Two Interface Method'.
    WRITE / it~v_txt.
  ENDMETHOD.                    "it~mit
ENDCLASS.                    "cls2 IMPLEMENTATION

START-OF-SELECTION.
  DATA: obj1 TYPE REF TO cls1,
        obj2 TYPE REF TO cls2.
  CREATE OBJECT: obj1, obj2.
  CALL METHOD: obj1->it~mit,
               obj2->it~mit.


The output is following:

Nested Interface

Nested Interface


We can create nested Interface by declaring one Interface in another Interface. We know to declare Interface in the class. The same syntax is followed here. In the class we only have to declare the Final Interface in public section.

The following program contains Interface it1 and it2. It2 declares it1 inside. In the it1 we have two methods mit1 and mit2. Similarly in the it2 we have two methods mit1 and mit2. Now in mit1 of it1 we Select from EKKO and mit2 of it1 we Select from EKPO for all entries in internal table it_ekko. Next we have mit1 in it2 and mit2 in it2. In mit1 we are preparing the final output table whereas in mit2 we are preparing the Output. After all these in start of selection we create an object obj referenced to class cls. Next we call method mit1 and mit2 of it1 and mit1 and mit2 of it2 by object obj.


*&---------------------------------------------------------------------*
*& Report  ZSR_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zsr_test.

TABLES: ekko, ekpo.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECT-OPTIONS s_ebeln FOR ekko-ebeln OBLIGATORY.
SELECTION-SCREEN END OF BLOCK b1.

*----------------------------------------------------------------------*
*       INTERFACE it1
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
INTERFACE it1.
  METHODS: mit1, mit2.
ENDINTERFACE.                    "it1

*----------------------------------------------------------------------*
*       INTERFACE it2
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
INTERFACE it2.
  METHODS: mit1, mit2.
  INTERFACES it1.
ENDINTERFACE.                    "it2

*----------------------------------------------------------------------*
*       CLASS cls DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls DEFINITION.

  PUBLIC SECTION.
    TYPES: BEGIN OF ty_ekko,
            ebeln TYPE ekko-ebeln,
            bukrs TYPE ekko-bukrs,
            lifnr TYPE ekko-lifnr,
           END OF ty_ekko,

           BEGIN OF ty_ekpo,
            ebeln TYPE ekpo-ebeln,
            ebelp TYPE ekpo-ebelp,
            matnr TYPE ekpo-matnr,
            werks TYPE ekpo-werks,
            lgort TYPE ekpo-lgort,
           END OF ty_ekpo,

           BEGIN OF ty_out,
            ebeln TYPE ekpo-ebeln,
            ebelp TYPE ekpo-ebelp,
            matnr TYPE ekpo-matnr,
            werks TYPE ekpo-werks,
            lgort TYPE ekpo-lgort,
            bukrs TYPE ekko-bukrs,
            lifnr TYPE ekko-lifnr,
           END OF ty_out.

    DATA: wa_ekko TYPE ty_ekko,
          wa_ekpo TYPE ty_ekpo,
          wa_out  TYPE ty_out,
          it_ekko TYPE STANDARD TABLE OF ty_ekko,
          it_ekpo TYPE STANDARD TABLE OF ty_ekpo,
          it_out  TYPE STANDARD TABLE OF ty_out.

    INTERFACES it2.

ENDCLASS.                    "cls DEFINITION

*----------------------------------------------------------------------*
*       CLASS cls IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls IMPLEMENTATION.
  METHOD it1~mit1.

    SELECT ebeln bukrs lifnr FROM ekko INTO TABLE it_ekko
    WHERE ebeln IN s_ebeln.

    IF sy-subrc = 0.
      SORT it_ekko BY ebeln.
    ELSE.
      MESSAGE 'Purchase Order Doesn''t Exist' TYPE 'I'.
      LEAVE LIST-PROCESSING.
    ENDIF.

  ENDMETHOD.                                                "it1~mit1

  METHOD it1~mit2.

    SELECT ebeln ebelp matnr werks lgort
      FROM ekpo INTO TABLE it_ekpo
      FOR ALL ENTRIES IN it_ekko
      WHERE ebeln = it_ekko-ebeln.

    IF sy-subrc = 0.
      SORT it_ekpo BY ebeln ebelp.
    ENDIF.

  ENDMETHOD.                                                "it1~mit2

  METHOD it2~mit1.

    IF it_ekpo IS NOT INITIAL.
      LOOP AT it_ekpo INTO wa_ekpo.
        wa_out-ebeln = wa_ekpo-ebeln.
        wa_out-ebelp = wa_ekpo-ebelp.
        wa_out-matnr = wa_ekpo-matnr.
        wa_out-werks = wa_ekpo-werks.
        wa_out-lgort = wa_ekpo-lgort.

        READ TABLE it_ekko INTO wa_ekko
        WITH KEY ebeln = wa_ekpo-ebeln BINARY SEARCH.
        IF sy-subrc = 0.
          wa_out-bukrs = wa_ekko-bukrs.
          wa_out-lifnr = wa_ekko-lifnr.
        ENDIF.

        APPEND wa_out TO it_out.
        CLEAR: wa_out, wa_ekko, wa_ekpo.
      ENDLOOP.
    ENDIF.

  ENDMETHOD.                                                "it2~mit1

  METHOD it2~mit2.

    IF it_out IS NOT INITIAL.
      LOOP AT it_out INTO wa_out.
        AT FIRST.
          WRITE: / 'Purchase Order',
                18 'Item',
                26 'Material',
                48 'Plant',
                55 'Storage',
                65 'Company',
                75 'Vendor'.
          ULINE.
          SKIP.
        ENDAT.

        WRITE: / wa_out-ebeln,
              18 wa_out-ebelp,
              26 wa_out-matnr,
              48 wa_out-werks,
              55 wa_out-lgort,
              65 wa_out-bukrs,
              75 wa_out-lifnr.
      ENDLOOP.
    ENDIF.

  ENDMETHOD.                                                "it2~mit2
ENDCLASS.                    "cls IMPLEMENTATION

START-OF-SELECTION.
  DATA obj TYPE REF TO cls.
  CREATE OBJECT obj.
  CALL METHOD: obj->it1~mit1,
               obj->it1~mit2,
               obj->it2~mit1,
               obj->it2~mit2.


Below is the Output:


Output:

Interface Static Attribute and Method are Accessed Directly

Interface Static Attribute and Method are Accessed Directly


Static attribute and method of Interface can be accessed directly in the data processing as of class. There is no need to create object for class.

Following program contains an interface where we have defined constants, static data and static method. The program contains a class which defines the interface and implements its method. Now in the start of selection we are valuing the class data directly by cls=>it~cls_var = 'Interface Data valued directly' statement and calling the method directly by call method cls=>it~cls_mit statement.

*&---------------------------------------------------------------------*
*& Report  ZSR_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zsr_test.

*----------------------------------------------------------------------*
*       INTERFACE it
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
INTERFACE it.
  CONSTANTS c_var TYPE char40 VALUE 'SAP ABAP Object Oriented'.
  CLASS-DATA cls_var TYPE char50.
  CLASS-METHODS cls_mit.
ENDINTERFACE.                    "it

*----------------------------------------------------------------------*
*       CLASS cls DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls DEFINITION.
  PUBLIC SECTION.
    INTERFACES it.
ENDCLASS.                    "cls DEFINITION

*----------------------------------------------------------------------*
*       CLASS cls IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls IMPLEMENTATION.
  METHOD it~cls_mit.
    WRITE: / 'Interface Method',
           / it~cls_var,
           / it~c_var.
  ENDMETHOD.                    "it~cls_mit
ENDCLASS.                    "cls IMPLEMENTATION

START-OF-SELECTION.
  cls=>it~cls_var = 'Interface Data valued directly'.
  CALL METHOD cls=>it~cls_mit.


The output is below:

Interface can be Instantiated

Interface can be Instantiated


Interface can be instantiated if the object is referenced to that interface. Here the class instance variable will have to be moved to the interface instance variable.

Following is a program where we have declared an interface containing constant, data and a method. Now the class definition contains only the interface in the public section. After that the method is implemented accordingly. In the start of selection we have created objects of the class. Here we have moved the class object variable to the interface variable and then we have called the method directly from the interface object variable.

*&---------------------------------------------------------------------*
*& Report  ZSR_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zsr_test.

*----------------------------------------------------------------------*
*       INTERFACE it
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
INTERFACE it.
  CONSTANTS c_var TYPE char40 VALUE 'SAP ABAP Object Oriented'.
  DATA var TYPE char50.
  METHODS mit.
ENDINTERFACE.                    "it

*----------------------------------------------------------------------*
*       CLASS cls DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls DEFINITION.
  PUBLIC SECTION.
    INTERFACES it.
ENDCLASS.                    "cls DEFINITION

*----------------------------------------------------------------------*
*       CLASS cls IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cls IMPLEMENTATION.
  METHOD it~mit.
    it~var = 'Interface Attribute'.
    WRITE: / 'Interface Method',
           / it~var,
           / it~c_var.
  ENDMETHOD.                    "it~mit
ENDCLASS.                    "cls IMPLEMENTATION

START-OF-SELECTION.
  DATA: obj_it TYPE REF TO it,
        obj    TYPE REF TO cls.
  CREATE OBJECT obj.
  obj_it = obj.
  CALL METHOD obj_it->mit.


The following is the output:

Abstract Method in Interface

Abstract Method in Interface


Abstract method is a method which cannot be implemented in the same class. Only sub class can implement an abstract method by redefinition. Important point is that the abstract method can be declared in an abstract class only. Now Interface can have an abstract method which must be declared in an abstract class as INTERFACES it ABSTRACT METHODS mit2 where mit2 is the abstract method. So mit2 will have to be implemented in any sub class by redefinition.

In the following program we have declared an Interface it where a text data and two methods mit1 and mit2 are there. Method mit2 is an abstract method so it will be declared in an abstract class. Now we are defining parent class as an abstract class where we are declaring the abstract interface method with the statement of INTERFACES it ABSTRACT METHODS mit2. In the implementation part we have implemented mit1 in parent class because abstract method mit2 cannot be implemented in the same class. So we have defined child class inheriting from parent class. We have redefined the abstract method as METHODS it~mit2 REDEFINITION in this child class. And then we can implement this properly. Finally in the start of selection we call these two methods by the child class object since abstract parent class cannot be instantiated.

*&---------------------------------------------------------------------*
*& Report  ZSR_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zsr_test.

*----------------------------------------------------------------------*
*       INTERFACE it
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
INTERFACE it.
  DATA v_txt TYPE char50.
  METHODS: mit1, mit2.
ENDINTERFACE.                    "it

*----------------------------------------------------------------------*
*       CLASS parent DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS parent DEFINITION ABSTRACT.
  PUBLIC SECTION.
    INTERFACES it ABSTRACT METHODS mit2.
ENDCLASS.                    "parent DEFINITION

*----------------------------------------------------------------------*
*       CLASS parent IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS parent IMPLEMENTATION.
  METHOD it~mit1.
    it~v_txt = 'Abstract Parent Class - Normal Method'.
    WRITE / it~v_txt.
  ENDMETHOD.                                                "it~mit1
ENDCLASS.                    "parent IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS child DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS child DEFINITION INHERITING FROM parent.
  PUBLIC SECTION.
    METHODS it~mit2 REDEFINITION.
ENDCLASS.                    "child DEFINITION

*----------------------------------------------------------------------*
*       CLASS child IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS child IMPLEMENTATION.
  METHOD it~mit2.
    it~v_txt = 'Normal Child Class - Abstract Method'.
    WRITE / it~v_txt.
  ENDMETHOD.                                                "it~mit2
ENDCLASS.                    "child IMPLEMENTATION

START-OF-SELECTION.
  DATA obj TYPE REF TO child.
  CREATE OBJECT obj.
  CALL METHOD: obj->it~mit1,
               obj->it~mit2.


The output is following:

Final Method in Interface

Final Method in Interface


Final method is a method which cannot be redefined by sub classes. So as in Interface final method can be declared and implemented similar to a class final method. Here the interface needs to be declared in a class as INTERFACE it FINAL METHODS mit2 where mit2 is the final method.

In the following program we have defined one interface under which two methods have been declared. Inside the class we mention the second method is final. Again we have declared a subclass and redefined the first method. Now at the time of calling, we call two methods from two different objects of two classes.


REPORT  zsr_test NO STANDARD PAGE HEADING.

*----------------------------------------------------------------------*
*       INTERFACE i_interface
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
INTERFACE i_interface.
  DATA v_test TYPE char40.
  METHODS: m_normal,
           m_final.
ENDINTERFACE.                    "i_interface

*----------------------------------------------------------------------*
*       CLASS cl_parent DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_parent DEFINITION.
  PUBLIC SECTION.
    INTERFACES i_interface FINAL METHODS m_final.
ENDCLASS.                    "cl_parent DEFINITION

*----------------------------------------------------------------------*
*       CLASS cl_parent IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_parent IMPLEMENTATION.
  METHOD i_interface~m_normal.
    i_interface~v_test = 'I am normal Method from Parent class'.
    WRITE: /3 i_interface~v_test.
  ENDMETHOD.                    "i_interface~m_normal

  METHOD i_interface~m_final.
    i_interface~v_test = 'I am final Method from Parent class'.
    WRITE: /3 i_interface~v_test.
  ENDMETHOD.                    "i_interface~m_final
ENDCLASS.                    "cl_parent IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS cl_child DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_child DEFINITION INHERITING FROM cl_parent.
  PUBLIC SECTION.
    METHODS i_interface~m_normal REDEFINITION.
ENDCLASS.                    "cl_child DEFINITION

*----------------------------------------------------------------------*
*       CLASS cl_child IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_child IMPLEMENTATION.
  METHOD i_interface~m_normal.
    i_interface~v_test = 'I am redefined Method from Child class'.
    WRITE: /3 i_interface~v_test.
  ENDMETHOD.                    "i_interface~m_normal
ENDCLASS.                    "cl_child IMPLEMENTATION

START-OF-SELECTION.  DATA: obj_parent TYPE REF TO cl_parent,
        obj_child  TYPE REF TO cl_child.

  CREATE OBJECT: obj_parent,
                 obj_child.

  CALL METHOD: obj_parent->i_interface~m_normal,
               obj_parent->i_interface~m_final,

               obj_child->i_interface~m_normal,
               obj_child->i_interface~m_final.

The following is the Output: