ABAP CLASS and METHOD: Object-Oriented Programming

Category
ABAP-Statements
Published
Author
Johannes

The CLASS statement is the foundation of object-oriented programming (OOP) in ABAP. With classes, you can combine data (attributes) and functions (methods) into reusable units.

Basic Concept

A class is a template (blueprint) for objects. It defines:

  • Attributes: Variables that store the state of an object
  • Methods: Functions that define the behavior of an object

An object is a concrete instance of a class.

Syntax

Class Definition

CLASS <classname> DEFINITION.
PUBLIC SECTION.
" Publicly accessible elements
DATA: <attribute> TYPE <type>.
METHODS: <method> [IMPORTING/EXPORTING/RETURNING ...].
PROTECTED SECTION.
" Only accessible to this class and subclasses
PRIVATE SECTION.
" Only accessible within this class
ENDCLASS.

Class Implementation

CLASS <classname> IMPLEMENTATION.
METHOD <method>.
" Method logic
ENDMETHOD.
ENDCLASS.

Visibility Sections

SectionAccess
PUBLICAccessible from everywhere
PROTECTEDOnly the class itself and subclasses
PRIVATEOnly within the class

Examples

1. Define and Use a Simple Class

" Definition
CLASS lcl_counter DEFINITION.
PUBLIC SECTION.
METHODS: increment,
get_value RETURNING VALUE(rv_value) TYPE i.
PRIVATE SECTION.
DATA: mv_count TYPE i VALUE 0.
ENDCLASS.
" Implementation
CLASS lcl_counter IMPLEMENTATION.
METHOD increment.
mv_count = mv_count + 1.
ENDMETHOD.
METHOD get_value.
rv_value = mv_count.
ENDMETHOD.
ENDCLASS.
" Usage
START-OF-SELECTION.
DATA: lo_counter TYPE REF TO lcl_counter.
" Create object
CREATE OBJECT lo_counter.
" Or modern: lo_counter = NEW #( ).
lo_counter->increment( ).
lo_counter->increment( ).
WRITE: / 'Counter value:', lo_counter->get_value( ).
" Output: Counter value: 2

2. Class with Constructor

The constructor is a special method that is automatically called when creating an object:

CLASS lcl_person DEFINITION.
PUBLIC SECTION.
METHODS: constructor IMPORTING iv_name TYPE string
iv_age TYPE i,
get_info RETURNING VALUE(rv_info) TYPE string.
PRIVATE SECTION.
DATA: mv_name TYPE string,
mv_age TYPE i.
ENDCLASS.
CLASS lcl_person IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
mv_age = iv_age.
ENDMETHOD.
METHOD get_info.
rv_info = |{ mv_name } is { mv_age } years old.|.
ENDMETHOD.
ENDCLASS.
" Usage
DATA: lo_person TYPE REF TO lcl_person.
" Create object with constructor parameters
lo_person = NEW #( iv_name = 'John Smith' iv_age = 30 ).
WRITE: / lo_person->get_info( ).
" Output: John Smith is 30 years old.

3. Methods with Parameters

CLASS lcl_calculator DEFINITION.
PUBLIC SECTION.
METHODS: add IMPORTING iv_a TYPE i
iv_b TYPE i
RETURNING VALUE(rv_result) TYPE i,
divide IMPORTING iv_dividend TYPE i
iv_divisor TYPE i
EXPORTING ev_result TYPE f
RAISING cx_sy_zerodivide.
ENDCLASS.
CLASS lcl_calculator IMPLEMENTATION.
METHOD add.
rv_result = iv_a + iv_b.
ENDMETHOD.
METHOD divide.
IF iv_divisor = 0.
RAISE EXCEPTION TYPE cx_sy_zerodivide.
ENDIF.
ev_result = iv_dividend / iv_divisor.
ENDMETHOD.
ENDCLASS.
" Usage
DATA: lo_calc TYPE REF TO lcl_calculator,
lv_sum TYPE i,
lv_quot TYPE f.
lo_calc = NEW #( ).
" RETURNING parameter: Functional method
lv_sum = lo_calc->add( iv_a = 5 iv_b = 3 ).
WRITE: / 'Sum:', lv_sum.
" EXPORTING parameter
lo_calc->divide( EXPORTING iv_dividend = 10
iv_divisor = 4
IMPORTING ev_result = lv_quot ).
WRITE: / 'Quotient:', lv_quot.

4. Static Methods and Attributes (CLASS-DATA/CLASS-METHODS)

Static elements belong to the class itself, not to individual objects:

CLASS lcl_id_generator DEFINITION.
PUBLIC SECTION.
CLASS-METHODS: get_next_id RETURNING VALUE(rv_id) TYPE i.
PRIVATE SECTION.
CLASS-DATA: gv_counter TYPE i VALUE 0.
ENDCLASS.
CLASS lcl_id_generator IMPLEMENTATION.
METHOD get_next_id.
gv_counter = gv_counter + 1.
rv_id = gv_counter.
ENDMETHOD.
ENDCLASS.
" Usage - no object needed!
DATA: lv_id1 TYPE i,
lv_id2 TYPE i.
lv_id1 = lcl_id_generator=>get_next_id( ). " => for static call
lv_id2 = lcl_id_generator=>get_next_id( ).
WRITE: / 'ID 1:', lv_id1. " 1
WRITE: / 'ID 2:', lv_id2. " 2

5. Inheritance

With INHERITING FROM, a class can inherit from another:

" Base class
CLASS lcl_vehicle DEFINITION.
PUBLIC SECTION.
METHODS: constructor IMPORTING iv_brand TYPE string,
get_brand RETURNING VALUE(rv_brand) TYPE string.
PROTECTED SECTION.
DATA: mv_brand TYPE string.
ENDCLASS.
CLASS lcl_vehicle IMPLEMENTATION.
METHOD constructor.
mv_brand = iv_brand.
ENDMETHOD.
METHOD get_brand.
rv_brand = mv_brand.
ENDMETHOD.
ENDCLASS.
" Derived class
CLASS lcl_car DEFINITION INHERITING FROM lcl_vehicle.
PUBLIC SECTION.
METHODS: constructor IMPORTING iv_brand TYPE string
iv_doors TYPE i,
get_info RETURNING VALUE(rv_info) TYPE string.
PRIVATE SECTION.
DATA: mv_doors TYPE i.
ENDCLASS.
CLASS lcl_car IMPLEMENTATION.
METHOD constructor.
" Call parent class constructor
super->constructor( iv_brand = iv_brand ).
mv_doors = iv_doors.
ENDMETHOD.
METHOD get_info.
rv_info = |{ mv_brand } with { mv_doors } doors|.
ENDMETHOD.
ENDCLASS.
" Usage
DATA: lo_car TYPE REF TO lcl_car.
lo_car = NEW #( iv_brand = 'BMW' iv_doors = 4 ).
WRITE: / lo_car->get_info( ).
" Output: BMW with 4 doors

6. Overriding Methods (REDEFINITION)

CLASS lcl_animal DEFINITION.
PUBLIC SECTION.
METHODS: speak RETURNING VALUE(rv_sound) TYPE string.
ENDCLASS.
CLASS lcl_animal IMPLEMENTATION.
METHOD speak.
rv_sound = 'Sound'.
ENDMETHOD.
ENDCLASS.
CLASS lcl_dog DEFINITION INHERITING FROM lcl_animal.
PUBLIC SECTION.
METHODS: speak REDEFINITION.
ENDCLASS.
CLASS lcl_dog IMPLEMENTATION.
METHOD speak.
rv_sound = 'Woof!'.
ENDMETHOD.
ENDCLASS.
" Usage
DATA: lo_animal TYPE REF TO lcl_animal,
lo_dog TYPE REF TO lcl_dog.
lo_animal = NEW lcl_animal( ).
lo_dog = NEW lcl_dog( ).
WRITE: / 'Animal:', lo_animal->speak( ). " Sound
WRITE: / 'Dog:', lo_dog->speak( ). " Woof!

Method Parameter Types

TypeDescriptionSyntax
IMPORTINGInput parameterIMPORTING iv_param TYPE type
EXPORTINGOutput parameterEXPORTING ev_param TYPE type
CHANGINGInput and outputCHANGING cv_param TYPE type
RETURNINGReturn value (functional)RETURNING VALUE(rv_param) TYPE type
RAISINGPossible exceptionsRAISING cx_exception

Object Creation

DATA: lo_obj TYPE REF TO lcl_myclass.
" Classic syntax
CREATE OBJECT lo_obj.
" With parameters
CREATE OBJECT lo_obj
EXPORTING
iv_param = 'Value'.
" Modern syntax (from 7.40)
lo_obj = NEW #( ).
lo_obj = NEW #( iv_param = 'Value' ).
" Inline declaration
DATA(lo_obj2) = NEW lcl_myclass( iv_param = 'Value' ).

Global vs. Local Classes

TypeDefinitionUsage
LocalIn program with CLASS ... DEFINITIONOnly in the same program
GlobalIn Class Builder (SE24)System-wide available

Local classes often start with lcl_ (local class), global ones with zcl_ or cl_.

Abstract Classes and Methods

Abstract classes cannot be instantiated:

CLASS lcl_shape DEFINITION ABSTRACT.
PUBLIC SECTION.
METHODS: get_area ABSTRACT RETURNING VALUE(rv_area) TYPE f.
ENDCLASS.
CLASS lcl_rectangle DEFINITION INHERITING FROM lcl_shape.
PUBLIC SECTION.
METHODS: constructor IMPORTING iv_width TYPE f
iv_height TYPE f,
get_area REDEFINITION.
PRIVATE SECTION.
DATA: mv_width TYPE f,
mv_height TYPE f.
ENDCLASS.
CLASS lcl_rectangle IMPLEMENTATION.
METHOD constructor.
mv_width = iv_width.
mv_height = iv_height.
ENDMETHOD.
METHOD get_area.
rv_area = mv_width * mv_height.
ENDMETHOD.
ENDCLASS.

Important Notes / Best Practice

  • Use descriptive names for classes and methods.
  • Keep methods short and focused (Single Responsibility).
  • Use PRIVATE for internal data to ensure encapsulation.
  • RETURNING parameters enable functional calls and chaining.
  • For polymorphic behavior, use INTERFACE instead of inheritance.
  • Handle errors with TRY...CATCH and exceptions.
  • Prefer the modern syntax NEW #( ) for object creation.
  • Global classes (SE24) are reusable and testable.