Обычно доступ к приватным и защищенным атрибутам объекта запрещен из-за пределов класса. Но порой необходимо нарушить эту концепцию по тем или иным причинам. Для этого в ABAP существует "дружба".
Класс может предоставить дружбу другим классам и интерфейсам. Этим друзьям предоставляется доступ ко всем компонентам класса, предлагающего дружбу, независимо от их раздела видимости или добавления READ-ONLY.
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
CLASS lcl_friend DEFINITION. PUBLIC SECTION. METHODS access. ENDCLASS. CLASS lcl_class_one DEFINITION FRIENDS lcl_friend. PRIVATE SECTION. DATA mv_variable TYPE string VALUE 'Private Attribute'. ENDCLASS. CLASS lcl_friend IMPLEMENTATION. METHOD access. DATA(lo_obj) = NEW lcl_class_one( ). cl_demo_output=>display( lo_obj->mv_variable ). ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA(lo_object) = NEW lcl_friend( ). lo_object->access( ). |
Также можно использовать интерфейс. Все классы реализованные от интерфеса будут получать достпук к приватным атрибутам дружественного класса.
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 |
INTERFACE lif_friend. METHODS: access. ENDINTERFACE. * CLASS lcl_access_class DEFINITION. PUBLIC SECTION. INTERFACES: lif_friend. ENDCLASS. * CLASS lcl_class_two DEFINITION FRIENDS lif_friend. PROTECTED SECTION. DATA: mv_attribute_prot TYPE string VALUE 'Protect Attribute'. PRIVATE SECTION. DATA: mv_attribute_priv TYPE string VALUE 'Private Attribute'. ENDCLASS. * CLASS lcl_access_class IMPLEMENTATION. METHOD lif_friend~access. DATA(lo_obj) = NEW lcl_class_two( ). cl_demo_output=>write_data( lo_obj->mv_attribute_prot ). cl_demo_output=>write_data( lo_obj->mv_attribute_priv ). cl_demo_output=>display( ). ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA(lo_object) = NEW lcl_access_class( ). lo_object->lif_friend~access( ). |
Более практический пример. Для получения доступа к приватному атрибуту alv можем унаследоваться от одного из классов друзей и также получим доступ к приватному атрибуту.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
CLASS demo_alv DEFINITION INHERITING FROM cl_salv_controller. PUBLIC SECTION. CLASS-METHODS access. ENDCLASS. CLASS demo_alv IMPLEMENTATION. METHOD access. DATA lo_alv TYPE REF TO cl_salv_table. DATA lt_alv TYPE TABLE OF t100 WITH DEFAULT KEY. TRY. cl_salv_table=>factory( IMPORTING r_salv_table = lo_alv CHANGING t_table = lt_alv ). CATCH cx_root. ENDTRY. cl_demo_output=>display( lo_alv->screen_start_line ). ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA(lo_object) = NEW demo_alv( ). lo_object->access( ). |
Стоит быть аккуратным с подобными действиями, т.к. это нарушает принцип инкапсуляции. Инкапсуляция — процесс разделения элементов абстракций, определяющих ее структуру (данные) и поведение (методы); инкапсуляция предназначена для изоляции контрактных обязательств абстракции (протокол/интерфейс) от их реализации.