ABAP ООП Ч.1. Введение в ООП.

 

Введение в объектно-ориентированное программирование.

До ООП все было основано на функциях и переменных без сосредоточения внимания на самом объекте. В ООП основное внимание уделяется объектам, которые представляют реальные объекты, с функциями и переменными, аппроксимирующими объекты.
Традиционное программирование было сосредоточено на разработке программной логики для управления данными, например логической процедуры, которая принимает входные данные, обрабатывает их и производит выходные данные. Однако ООП фокусируется на объекте, которым манипулируют, а не на логике манипулирования данными.

Если вы посмотрите вокруг, вы увидите много объектов реального мира, таких как ваша машина, ваша собака, ваш ноутбук и так далее. Каждый из этих объектов реального мира представлен как программный объект в ООП. Объекты реального мира имеют две характеристики: состояния и поведение. Например, у автомобиля есть такие состояния, как его текущая передача, текущая скорость и т. д., а также поведение, такое как переключение передач, торможение и т. д. Программные объекты, представляющие объекты реального мира, также имеют состояния и поведение; программные объекты хранят свои состояния в переменных (называемых атрибутами) и содержат функции (называемые методами) для управления или отображения состояний объекта. Например, объект автомобиля может иметь атрибуты для хранения текущей скорости, текущей передачи и т. д., а также методы для чтения текущей скорости или переключения передачи.

Методы оперируют внутренним состоянием объекта; то есть они могут получить доступ к атрибутам своего собственного объекта и служить механизмом связи между объектами. Сокрытие этого внутреннего состояния объекта и маршрутизация всего доступа к объекту через его методы называется инкапсуляцией.

Иногда объект может иметь много общего с другими объектами, но при этом иметь свои собственные особенности. Например, горный велосипед может иметь все функции дорожного велосипеда, а также некоторые функции, характерные только для горных велосипедов. Концепция наследования помогает нам использовать существующий код и избегать избыточности кода при расширении функциональности.

Определение состояний и поведения объектов реального мира — это первый шаг к тому, чтобы начать мыслить в терминах ООП. Прежде чем продолжить изучение ООП, давайте рассмотрим простое приложение процедурного программирования, которое вычисляет индекс массы тела человека (ИМТ). Затем мы рассмотрим, как это приложение может быть разработано с использованием ООП. Для этого примера мы можем создать функциональный модуль с тремя параметрами интерфейса: ростом, весом и ИМТ. Мы можем передать в функцию рост и вес человека и получить в результате рассчитанный ИМТ.
FUNCTION ZCALCULATE_BMI.
*"---------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(IV_HEIGHT) TYPE I
*" REFERENCE(IV_WEIGHT) TYPE I
*" EXPORTING
*" REFERENCE(EV_BMI) TYPE I
EV_BMI = IV_WEIGHT / IV_HEIGHT.
ENDFUNCTION.
REPORT ZCA_BMI.
  
DATA lv_bmi TYPE I.
PARAMETERS: p_height TYPE I,
			P_weight TYPE I.
            
CALL FUNCTION 'ZCALCULATE_BMI'
	EXPORTING
      iv_height = p_height
      iv_weight = p_weight
	IMPORTING
      ev_bmi 	= lv_bmi.

WRITE: 'Ваш индекс массы тела ' , lv_bmi.
 
Когда функциональный модуль вызывается в программе, вся функциональная группа, к которой принадлежит этот функциональный модуль, загружается в память (внутренний сеанс), которой назначена основная программа. Каждый последующий вызов этого функционального модуля в программе будет обращаться к существующему экземпляру в памяти, а не к загрузке нового экземпляра.

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

Если вы вызовете функциональный модуль zcalculate_bmi в программе для расчета ИМТ нескольких человек, функциональный модуль не сможет узнать человека, для которого рассчитывается ИМТ. Вы можете определить глобальную переменную в функциональной группе для хранения имени человека, чтобы другие функциональные модули функциональной группы могли использовать эту информацию, но легко потерять все эти переменные в коде — и даже в этом случае этот дизайн может поддерживать только одного человека за раз в приложении.

Фокус функционального модуля здесь состоит в том, чтобы взять определенный ввод и обработать его для получения результата. ООП смещает фокус на объект. В этом примере мы определяем объект, представляющий человека, а затем определяем атрибуты и методы для хранения и обработки ИМТ человека.

Классы

Объекты инкапсулируют данные и создают функции для управления этими данными. Характеристики (называемые атрибутами) и функции (называемые методами) объекта помещаются в один пакет. Определение этого пакета называется классом. Чтобы использовать объекты в программе, должны быть определены классы, поскольку объект существует как экземпляр класса.
  
REPORT zca_bmi.
CLASS lcl_person DEFINITION.
  PUBLIC SECTION.
    TYPES mty_packed  TYPE p LENGTH 4 DECIMALS 2.
    METHODS set_height  IMPORTING iv_height TYPE mty_packed.
    METHODS set_weight  IMPORTING iv_weight TYPE mty_packed.
    METHODS set_bmi.
    METHODS get_bmi RETURNING VALUE(rv_bmi) TYPE mty_packed.
  PRIVATE SECTION.
    DATA: mv_bmi    TYPE i,
          mv_height TYPE i,
          mv_weight TYPE i.
ENDCLASS.
CLASS lcl_person IMPLEMENTATION.
  METHOD set_height.
    mv_height = iv_height.
  ENDMETHOD.
  METHOD set_weight.
    mv_weight = iv_weight.
  ENDMETHOD.
  METHOD set_bmi.
    mv_bmi = mv_height / mv_weight.
  ENDMETHOD.
  METHOD get_bmi.
    rv_bmi = mv_bmi.
  ENDMETHOD.
ENDCLASS.

DATA go_vadim TYPE  REF TO  lcl_person.
DATA go_ivan TYPE  REF TO  lcl_person.

START-OF-SELECTION.
  CREATE OBJECT go_vadim.
  go_vadim->set_height( EXPORTING iv_height = 165 ).
  go_vadim->set_weight( EXPORTING iv_weight = 50 ).
  go_vadim->set_bmi( ).
  WRITE :/'Индекс массы тела Вадима ', go_vadim->get_bmi( ).
  CREATE OBJECT go_ivan.
  go_ivan->set_height( EXPORTING iv_height = 175 ).
  go_ivan->set_weight( EXPORTING iv_weight = 80 ).
  go_ivan->set_bmi( ).
  WRITE :/'Индекс массы тела Ивана' , go_ivan->get_bmi( ).
  IF go_vadim->get_bmi( ) GT go_ivan->get_bmi( ).
    WRITE :/'Вадим толще, чем Ивана'.
  ELSE.
    WRITE :/'Ивана толще, чем  Вадим'.
  ENDIF.
   
Класс состоит из двух разделов: раздела определения (DEFINITION) и раздела реализации (IMPLEMENTATION). В разделе определения мы определяем компоненты класса, такие как атрибуты, методы и события. Атрибуты класса хранят состояние объекта, а методы реализуют логику для управления поведением объекта путем доступа к атрибутам.

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

Каждый компонент класса может принадлежать определенному разделу видимости, например общедоступному (PUBLIC SECTION), защищенному (PROTECTED SECTION) или частному (PRIVATE SECTION). Раздел видимости позволяет инкапсулировать данные, устанавливая ограничения на доступ к компоненту класса. Например, к компоненту, принадлежащему разделу общедоступной видимости, внешние объекты и программы могут обращаться без каких-либо ограничений, а к компоненту, принадлежащему разделу частной видимости, могут обращаться только методы того же класса.

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

Мы определили класс LCL_PERSON, состоящий из атрибутов MV_HEIGHT, MV_WEIGHT и MV_BMI, в разделе частной видимости. Поскольку эти атрибуты являются частными, внешние объекты или программы не могут получить к ним прямой доступ. Чтобы манипулировать этими атрибутами, мы определили методы установки и получения в общедоступном разделе файла.
класс. Методы-сеттеры позволяют вам установить значение атрибута, а методы-геттеры позволяют вам считывать значение атрибута. Определение атрибутов в приватном разделе и предоставление методов установки и получения для управления атрибутами обеспечивает больший контроль, например, проверку данных перед изменением состояния объекта.

Например, мы можем избежать установки недопустимого значения для роста человека, проверив ввод в методе SET_HEIGHT. В программе мы определили две переменные ссылки на объект с именами GO_VADIM и GO_IVAN, относящиеся к классу LCL_PERSON. Объект существует как экземпляр класса, и каждый класс может иметь несколько экземпляров. Переменная ссылки на объект изначально содержит пустое значение, пока объект не будет создан с помощью инструкции CREATE OBJECT. После создания экземпляра объекта переменная ссылки на объект содержит ссылку (указатель) на объект в памяти, и доступ к объекту осуществляется с использованием переменной ссылки на объект. Ссылочные переменные объекта также называются ссылочными объектами и определяются с помощью дополнения TYPE REF TO.

В отличие от функциональных модулей, здесь каждый ссылочный объект занимает свое место в памяти, и в программе может быть определено несколько экземпляров класса, причем каждый экземпляр работает со своими данными.


Перевод книги #Complete ABAP / Kiran Bandari

Комментарии