В объектно-ориентированных языках доступ к приватным или защищенным методам или атрибутам должен быть запрещен. Если кто либо попытается к ним обратиться то компилятор выдаст ошибку. Однако иногда нам необходимо получить к ним доступ, в ABAP это возможно с помощью использования концепции «друзей».
Использование данной концепции возможно с помощью ключевого слова FRIENDS в атрибуте класса. В следующем примере показан класс lcl_me который определяет в качестве друга класс lcl_friend. У класса lcl_friend создан метод access_a1_of_class1 который выводит переменную из области видимости PRIVATE класса lcl_me.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
CLASS lcl_me DEFINITION FRIENDS lcl_friend. PRIVATE SECTION. DATA: a1 TYPE STRING VALUE 'I am A1 of LCL_ME'. ENDCLASS. "lcl_me DEFINITIONREPORT zdemo_simple_friend. * CLASS lcl_friend DEFINITION. PUBLIC SECTION. METHODS: access_a1_of_class1. ENDCLASS. "lcl_friend DEFINITION * CLASS lcl_me DEFINITION FRIENDS lcl_friend. PRIVATE SECTION. DATA: a1 TYPE STRING VALUE 'I am A1 of LCL_ME'. ENDCLASS. "lcl_me DEFINITION * CLASS lcl_friend IMPLEMENTATION. METHOD access_a1_of_class1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / lo_class1->a1. ENDMETHOD. "access_a1_of_class1 ENDCLASS. "lcl_friend IMPLEMENTATION * START-OF-SELECTION. DATA: lo_friend TYPE REF TO lcl_friend. CREATE OBJECT lo_friend. lo_friend->access_a1_of_class1( ). |
Таким образом класс lcl_friend получает неограниченный доступ к lcl_me. Все классы наследуемые от lcl_friend будут так же иметь доступ ко все приватным атрибутам lcl_me:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
REPORT znp_demo_friend_kids. * CLASS lcl_friend DEFINITION. PUBLIC SECTION. METHODS: access_a1_of_class1. ENDCLASS. "lcl_friend DEFINITION * CLASS lcl_friend_kids DEFINITION INHERITING FROM lcl_friend. PUBLIC SECTION. METHODS: my_access_a1. ENDCLASS. "lcl_friend_kids DEFINITION * CLASS lcl_me DEFINITION FRIENDS lcl_friend. PRIVATE SECTION. DATA: a1 TYPE STRING VALUE 'I am A1 of LCL_ME'. ENDCLASS. "lcl_me DEFINITION * CLASS lcl_friend IMPLEMENTATION. METHOD access_a1_of_class1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / lo_class1->a1. ENDMETHOD. "access_a1_of_class1 ENDCLASS. "lcl_friend IMPLEMENTATION * CLASS lcl_friend_kids IMPLEMENTATION. METHOD my_access_a1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / 'Accessing A1 from LCL_FRIEND_KIDS'. WRITE: / lo_class1->a1. ENDMETHOD. "my_access_a1 ENDCLASS. "lcl_friend_kids IMPLEMENTATION * START-OF-SELECTION. " Friend kid DATA: lo_friend_kids TYPE REF TO lcl_friend_kids. CREATE OBJECT lo_friend_kids. lo_friend_kids->my_access_a1( ). |
Кроме того в качестве «друга» мы можем обозначить интерфейс. Все классы которые реализуют данный интерфейс будут иметь такой же доступ если бы они сами были «друзьями».
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
REPORT znp_demo_friend_intf. * INTERFACE lif_friend. METHODS: access_a1_of_class1. ENDINTERFACE. "lif_friend * CLASS lcl_friend DEFINITION. PUBLIC SECTION. INTERFACES: lif_friend. ENDCLASS. "lcl_friend DEFINITION * CLASS lcl_friend_2 DEFINITION. PUBLIC SECTION. INTERFACES: lif_friend. ENDCLASS. "lcl_friend_2 DEFINITION * CLASS lcl_me DEFINITION FRIENDS lif_friend. PRIVATE SECTION. DATA: a1 TYPE STRING VALUE 'I am A1 of LCL_ME'. ENDCLASS. "lcl_me DEFINITION * CLASS lcl_friend IMPLEMENTATION. METHOD lif_friend~access_a1_of_class1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / 'Accessing A1 from LCL_FRIEND via LIF_FRIEND'. WRITE: / lo_class1->a1. ENDMETHOD. "access_a1_of_class1 ENDCLASS. "lcl_friend IMPLEMENTATION * CLASS lcl_friend_2 IMPLEMENTATION. METHOD lif_friend~access_a1_of_class1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / 'Accessing A1 from LCL_FRIEND_2 via LIF_FRIEND'. WRITE: / lo_class1->a1. ENDMETHOD. "my_access_a1 ENDCLASS. "lcl_friend_2 IMPLEMENTATION * START-OF-SELECTION. " Friend Access via Interface DATA: lo_friend TYPE REF TO lif_friend. CREATE OBJECT lo_friend TYPE lcl_friend. lo_friend->access_a1_of_class1( ). " another friend CREATE OBJECT lo_friend TYPE lcl_friend_2. lo_friend->access_a1_of_class1( ). |
Однако наследуемые классы от lcl_me не будут являться друзьями класса lcl_friend. Другими словами дружба не наследуется напрямую, она создается в определении класса.
Доступ к приватным данным CL_GUI_ALV_GRID
Благодаря тому что интерфейс IF_ALV_RM_GRID_FRIEND в CL_GUI_ALV_GRID объявлен как интерфейс друга, любой Ваш класс реализующий данный интерфейс получит доступ к приватным данным объектов этого класса.
Доступ к приватным данным можно так же получить передав их по ссылке.