SAPфорум.RU
https://sapboard.ru/forum/

Динамический вызов метода при наследовании
https://sapboard.ru/forum/viewtopic.php?f=13&t=96248
Страница 1 из 1

Автор:  Sam Stone [ Вт, апр 03 2018, 09:19 ]
Заголовок сообщения:  Динамический вызов метода при наследовании

Добрый день.

Вот такой пример:
Code:
REPORT.

INTERFACE lif_common.
  METHODS command IMPORTING command TYPE csequence.
ENDINTERFACE.

CLASS lcl_common DEFINITION ABSTRACT.
  PUBLIC SECTION.
    INTERFACES lif_common.
ENDCLASS.

CLASS lcl_common IMPLEMENTATION.
  METHOD lif_common~command.
    DATA(method) = |DO_{ command }|.
    TRY .
      CALL METHOD me->(method).
    CATCH CX_SY_DYN_CALL_ILLEGAL_METHOD INTO DATA(oref).
      WRITE:/ oref->get_text( ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_t1 DEFINITION INHERITING FROM lcl_common.
  PUBLIC SECTION.
    METHODS do_t2.
  PROTECTED SECTION.
    METHODS do_t1.
ENDCLASS.

CLASS lcl_t1 IMPLEMENTATION.
  METHOD do_t1.
    WRITE:/ 'lcl_t1->do_t1 protected'.
  ENDMETHOD.

  METHOD do_t2.
    WRITE:/ 'lcl_t1->do_t2 public'.
  ENDMETHOD.
ENDCLASS.


START-OF-SELECTION.

  DATA obj TYPE REF TO lif_common.

  obj = new lcl_t1( ).
  obj->command( command = 'T1' ).
  obj->command( command = 'T2' ).

В отладке при вызове CALL METHOD me->(method) me имеет тип LCL_T1. Т.е. вроде как класс хочет вызвать свой защищенный метод. Почему тогда выдается исключение? Потому что реализация вызова в родителе находится?..

Автор:  NeMurometz [ Вт, апр 03 2018, 09:40 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

Добрый день!
Добавьте интерфейс в друзья.
Code:
CLASS lcl_t1 DEFINITION INHERITING FROM lcl_common FRIENDS lif_common.

Автор:  Sam Stone [ Вт, апр 03 2018, 09:57 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

NeMurometz написал(а):
Добрый день!
Добавьте интерфейс в друзья.
Code:
CLASS lcl_t1 DEFINITION INHERITING FROM lcl_common FRIENDS lif_common.


Если у меня будет несколько наследников lcl_common, реализующих, например, разный функционал, мне каждому придется прописывать друга.

Автор:  ghost [ Вт, апр 03 2018, 10:17 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

читаем хелп по Protected Section и думаю вопрос сам по себе отпадет
Цитата:
All components of the class declared in the area behind the statement PROTECTED SECTION can be addressed directly only in the subclasses of the class and in the class itself (plus its friends), if allowed by the package concept. Protected methods in subclasses can be redefined.

Автор:  Sam Stone [ Вт, апр 03 2018, 10:37 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

Да, я знаю, что защищенные методы может вызывать только сам класс, его потомки и друзья.

В данном случае вызов динамический из родителя. Вопрос в чем: код метода lif_common~command вызвается на уровне родителя и поэтому доступ не положен, несмотря на то, что me имеет тип необходимого класса (lcl_t1 в данном случае) и вроде как класс вызывает свой защищенный метод?..

Т.е., условно логика такая получается:
1) Вызываем lcl_t1->command
2) lcl_t1 "говорит" - нет у меня такого метода, он у родителя есть
3) Выполнение уходит в lcl_common->command
4) lcl_common не имеет доступа к защищенному методу потомка
5) ошибка
?

Автор:  ghost [ Вт, апр 03 2018, 11:47 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

да верно, вызов осуществлен извне поэтому и исключение. И тут не важно что динамический вызов и тип ссылается на необходимый класс.

Автор:  AFH [ Ср, апр 04 2018, 04:43 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

Оффтоп. А вам не нужно что-то вроде Команда или Стратегия?

Автор:  Sam Stone [ Ср, апр 04 2018, 08:10 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

AFH написал(а):
Оффтоп. А вам не нужно что-то вроде Команда или Стратегия?


Неплохая мысль... Пощупаю, пожалуй, команду. Спасибо. Может хоть где-то присобачу паттерн :lol:

Автор:  matik [ Ср, апр 04 2018, 09:21 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

мои 5 копеек
про вызов protected метода вроде все просто

создавать callback-и или реализовывать интерфейс в ABAP не очень удобно (создавать DEFINITION и IMPLEMENTATION в локальных классах долго)
лямбда выражений тоже нет

передачу параметров в методы можно реализовать след-м способом
в 7.5 выглядит компактно

Code:
REPORT zzz1.

INTERFACE lif_common.
  METHODS command IMPORTING method TYPE csequence
                            params TYPE abap_parmbind_tab OPTIONAL.
ENDINTERFACE.

CLASS lcl_common DEFINITION ABSTRACT.
  PUBLIC SECTION.
    INTERFACES lif_common.
ENDCLASS.

CLASS lcl_common IMPLEMENTATION.
  METHOD lif_common~command.
    TRY .
        CALL METHOD me->(method)
          PARAMETER-TABLE params.
      CATCH cx_sy_dyn_call_illegal_method INTO DATA(oref).
        WRITE:/ oref->get_text( ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_t1 DEFINITION INHERITING FROM lcl_common.
  PUBLIC SECTION.
    METHODS print_name
      IMPORTING
        iv_name TYPE csequence.

    METHODS power_2
      IMPORTING
                iv_number        TYPE numeric
      RETURNING VALUE(rv_result) TYPE i.
ENDCLASS.

CLASS lcl_t1 IMPLEMENTATION.
  METHOD print_name.
    WRITE:/ iv_name COLOR 1.
  ENDMETHOD.

  METHOD power_2.
    rv_result = iv_number ** 2.
  ENDMETHOD.
ENDCLASS.


START-OF-SELECTION.

  DATA obj TYPE REF TO lif_common.

  obj = NEW lcl_t1( ).

  " Передача имени
  obj->command( method = 'PRINT_NAME' params = VALUE #(
   ( name  = 'IV_NAME'
     kind  = cl_abap_objectdescr=>exporting
     value = REF #( 'John Doe' )   )
  ) ).

  " Квадрат значения
  DATA: lv_result TYPE i.
  obj->command( method = 'POWER_2' params = VALUE #(
   ( name  = 'IV_NUMBER'
     kind  = cl_abap_objectdescr=>exporting
     value = REF #( 5 ) )
   ( name  = 'RV_RESULT'
     kind  = cl_abap_objectdescr=>receiving
     value = REF #( lv_result ) )
  ) ).
  WRITE / lv_result COLOR 2.

Автор:  Kengur [ Ср, апр 04 2018, 11:34 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

Скоро тут будет "как сделать аналог Javascript на ABAP" :D

Автор:  ghost [ Ср, апр 04 2018, 12:05 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

тут единственная ошибка в вашей реализации, что вы объявили метод как protected. смысла в этом не вижу.

Автор:  Удав [ Ср, апр 04 2018, 22:54 ]
Заголовок сообщения:  Re: Динамический вызов метода при наследовании

Kengur написал(а):
Скоро тут будет "как сделать аналог Javascript на ABAP" :D

:pivo:

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/