Части и компоненты класса.
Класс в ABAP состоит из двух разделов:
- Definition section
В разделе определения определяются различные компоненты класса, такие как атрибуты, события и методы.
- Implementation section
В разделе реализации класса мы реализуем методы, определенные в разделе определения. Методы реализуются между операторами METHOD и ENDMETHOD, и каждый метод, определенный в части определения, должен иметь реализацию в части реализации класса.
В классе доступны три важных типа компонентов:
- Methods
Методы используются для изменения состояния объекта и управления его поведением.
- Attributes
Атрибуты являются внутренними полями данных класса и хранят состояние объекта.
- Events
События определяются в области определения класса и могут вызываться во время выполнения объекта. Подходящий метод обработчика событий поддерживается в части реализации класса и запускается при возникновении соответствующего события. События позволяют динамически вызывать определенные методы во время выполнения объекта.
Например, если вы хотите выполнять определенные задачи, когда пользователь дважды щелкает строку вывода, вы можете поддерживать событие DOUBLE_CLICK, которое может быть вызвано этим событием. Зарегистрированный метод обработчика событий будет вызываться динамически при возникновении события.
Например, если вы хотите выполнять определенные задачи, когда пользователь дважды щелкает строку вывода, вы можете поддерживать событие DOUBLE_CLICK, которое может быть вызвано этим событием. Зарегистрированный метод обработчика событий будет вызываться динамически при возникновении события.
Компоненты класса можно разделить на следующие категории:
- Статические компоненты(Static components)
Доступ к статическим компонентам можно получить напрямую с помощью селектора компонентов класса=>. Статические компоненты ведут себя аналогично функциональным модулям, поскольку в программе существует только один экземпляр статического компонента.
- Компоненты экземпляра(Instance components)
К компонентам экземпляра нельзя получить доступ напрямую, используя имя класса. Чтобы получить доступ к компоненту-экземпляру, вам необходимо определить объект-ссылку в программе с помощью TYPE REF TO, а затем получить доступ к его атрибутам и методам через объект-ссылку с помощью селектора компонентов объекта ->.
Прежде чем можно будет получить доступ к атрибутам и методам через ссылочный объект, необходимо создать экземпляр ссылочного объекта с помощью инструкции CREATE OBJECT, которая создает экземпляр класса (объект, описываемый классом) в программе.
Прежде чем можно будет получить доступ к атрибутам и методам через ссылочный объект, необходимо создать экземпляр ссылочного объекта с помощью инструкции CREATE OBJECT, которая создает экземпляр класса (объект, описываемый классом) в программе.
Видимость
Компоненты класса могут иметь разные разделы видимости, такие как public(общедоступный), protected(защищенный) и private(частный). Видимость устанавливается в части определения класса. Видимость компонентов позволяет инкапсулировать данные и скрывать реализацию от внешнего мира.
METHOD
Метод может обращаться к другим компонентам того же объекта. Для доступа к атрибутам и методам одного и того же класса используется специальная переменная самоссылки me. Несмотря на то, что к компонентам класса можно получить доступ непосредственно из методов того же класса, для лучшей читабельности рекомендуется использовать переменную самоссылки me при доступе к тем же компонентам класса. Вы можете получить доступ как к статическим, так и к экземплярным компонентам из метода экземпляра, тогда как к статическим компонентам можно получить доступ только из статического метода.
Чтобы вызвать метод класса, мы можем либо использовать оператор CALL METHOD, либо напрямую использовать селектор компонентов объекта и круглые скобки.
............. CALL METHOD go_ivan->set_height " Вызов метода с использованием оператора EXPORTING iv_height = 165 *ИЛИ так go_ivan->set_height( EXPORTING iv_height = 165 ). " Короткая форма вызова метода .............
Метод может иметь параметры: importing(импорта), exporting(экспорта), changing(изменения) и returning(возврата). Импорт, экспорт и изменение параметров ведут себя аналогично параметрам, которые мы определяем в функциональных модулях. Например, данные импортируются через параметры импорта и экспортируются через параметры экспорта, а изменение параметров может использоваться как для импорта, так и для экспорта.
Методы, использующие возвращаемые параметры, называются функциональными методами. До SAP NetWeaver 7.4 функциональные методы могли иметь только один возвращаемый параметр и не иметь параметров экспорта. Однако в SAP NetWeaver 7.4 это ограничение снимается. Функциональные методы обычно используются, когда в вызывающую программу возвращается результат, который можно напрямую присвоить объекту данных в программе.
............. lv_bmi = go_ivan->get_bmi( ). .............
Наследование
Часто многие объекты отличаются друг от друга, но достаточно похожи, чтобы их можно было отнести к одному классу. Например, у животных и людей есть сердцебиение, поэтому класс может иметь метод get_heart_beat. Однако у собак есть длина хвоста, поэтому должен ли этот класс также иметь метод get_tail_length? Нет, мы можем определить другой класс как дочерний класс (называемый подклассом) родительского класса. Этот подкласс будет иметь все функции родительского класса, а также некоторые дополнительные функции. Это позволяет вам расширять функциональность ваших приложений, используя существующий код.
Давайте посмотрим на пример. Объекты предназначены для близкого представления реальных объектов, таких как принтер. Принтер может иметь внешний интерфейс, включая лоток для бумаги, клавиатуру и т. д., а основная функциональность принтера заключается в создании распечатки. Объекты ООП могут быть разработаны для представления этой установки.
CLASS lcl_printer DEFINITION. PUBLIC SECTION. METHODS print. ENDCLASS. CLASS lcl_printer IMPLEMENTATION. METHOD print. WRITE 'Документ напечатан'. ENDMETHOD. ENDCLASS.
Это базовый принтер, но что, если мы хотим расширить его функциональность? Например, если у нас есть новая модель принтера с функцией счетчика для отслеживания количества напечатанных копий, должны ли мы создавать всю логику принтера с нуля? Нет, мы можем определить подкласс, как показано ниже, который наследует все функциональные возможности базового принтера и расширяет их.
Класс LCL_PRINTER_WITH_COUNTER наследуется от класса LCL_PRINTER. Здесь LCL_PRINTER — это суперкласс (родительский класс), а LCL_PRINTER_WITH_COUNTER — подкласс (дочерний класс). Этот процесс наследования подклассом признаков суперкласса называется наследованием в ООП.
Обратите внимание на ключевое слово INHERITING FROM, используемое в определении класса LCL_PRINTER_WITH_COUNTER. Подкласс наследует все компоненты родительского класса. По умолчанию он будет иметь все атрибуты и методы, определенные в родительском классе. При необходимости методы, унаследованные в подклассе, могут быть переопределены для добавления функциональности.
Метод печати в подклассе LCL_PRINTER_WITH_COUNTER переопределяется для увеличения атрибута счетчика и вызывает метод печати родительского класса. Это эффективно расширяет функциональные возможности метода, используя существующие функциональные возможности, предоставляемые методом родительского класса. Поскольку один и тот же метод печати ведет себя по-разному в суперклассе и подклассе, это приводит к интересному поведению, называемому полиморфизмом (что означает наличие множества форм).
Теперь у нас есть принтер со счетчиком, и мы знаем, что счетчик увеличивается на единицу каждый раз, когда печатается документ. Однако какова будет его начальная стоимость? Как обеспечить, чтобы счетчик всегда начинался с того или иного начального значения? Эти детали решаются путем определения конструктора класса.
Существует два типа конструкторов:
- Instance constructor Конструктор экземпляра — это специальный метод, вызываемый при создании экземпляра объекта. Конструктор экземпляра вызывается для каждого объекта при его создании.
- Class constructor Конструктор класса — это специальный метод, вызываемый один раз для всего класса в одном внутреннем режиме. Конструктор класса может иметь максимум один экземпляр и один статический конструктор. У статического конструктора не может быть никаких параметров, тогда как у конструктора экземпляра могут быть только параметры импорта.
Определив параметры импорта для конструктора экземпляра, мы можем гарантировать, что объект всегда будет инициализирован до того, как будет осуществлен доступ к любому из его атрибутов или методов.
CLASS lcl_printer_with_counter DEFINITION INHERITING FROM lcl_printer. PUBLIC SECTION. DATA mv_counter TYPE i. METHODS constructor IMPORTING iv_count TYPE i. METHODS print REDEFINITION. ENDCLASS. CLASS lcl_printer_with_counter IMPLEMENTATION. METHOD constructor. CALL METHOD super->constructor. mv_counter = iv_count. ENDMETHOD. METHOD print. mv_counter = mv_counter + 1. CALL METHOD super->print. ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA lo_oref TYPE REF TO lcl_printer_with_counter. CREATE OBJECT lo_oref EXPORTING iv_count = 0.
Метод конструктора определен в части определения класса LCL_PRINTER_WITH_COUNTER с одним параметром импорта, iv_count. Поскольку класс LCL_PRINTER_WITH_COUNTER является подклассом класса принтера, конструктор суперкласса должен вызываться первым при реализации метода конструктора, даже если в суперклассе конструктор не определен. Это гарантирует правильную инициализацию всех компонентов суперкласса в дереве наследования. Если конструктор определен в суперклассе, он не будет унаследован подклассом. Это позволяет каждому классу в дереве наследования иметь собственный конструктор для инициализации его атрибутов в соответствии с требованиями.
Параметру iv_count конструктора присваивается значение при создании экземпляра ссылочного объекта lo_oref. Средство проверки синтаксиса выдаст ошибку, если обязательные параметры конструктора не будут переданы при создании экземпляра ссылочного объекта. Это гарантирует, что экземпляр объекта всегда создается правильно.
Теперь предположим, что у нас есть более продвинутая модель принтера, которая может печатать несколько копий вместе с основными функциями, предоставляемыми до сих пор. Чтобы создать этот принтер, мы унаследуем класс LCL_PRINTER_WITH_COUNTER и добавим дополнительные функции, как показано ниже.
CLASS lcl_multi_copy_printer DEFINITION INHERITING FROM lcl_printer_with_counter. PUBLIC SECTION. DATA mv_copies TYPE i. METHODS set_copies IMPORTING iv_copies TYPE i. METHODS print REDEFINITION. ENDCLASS. CLASS lcl_multi_copy_printer IMPLEMENTATION. METHOD set_copies. me->mv_copies = iv_copies. ENDMETHOD. METHOD print. DO mv_copies TIMES. CALL METHOD super->print. ENDDO. ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA oref TYPE REF TO lcl_multi_copy_printer. CREATE OBJECT oref EXPORTING iv_count = 0. oref->set_copies( 5 ). oref->print( ).
Мы определили класс LCL_MULTI_COPY_PRINTER, унаследованный от LCL_PRINTER_WITH_COUNTER. В классе LCL_MULTI_COPY_PRINTER мы определили метод set_copies, который получает параметр импорта копий и присваивает значение атрибуту копий. Мы переопределили метод печати для печати нескольких копий, вызвав метод в суперклассе в цикле DO.
Рекомендуется не разрешать прямой доступ к атрибутам класса и использовать методы для установки или получения значений атрибутов. Это дает нам больше контроля при манипулировании атрибутами. Методы, которые устанавливают значения, называются сеттеры, а методы, используемые для получения значений, называются геттеры. Методы установки имеют префикс set_, а методы получения — префикс get_.
Перевод книги #Complete ABAP / Kiran Bandari
Комментарии
Отправить комментарий