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 classENDCLASS.Class Implementation
CLASS <classname> IMPLEMENTATION. METHOD <method>. " Method logic ENDMETHOD.ENDCLASS.Visibility Sections
| Section | Access |
|---|---|
PUBLIC | Accessible from everywhere |
PROTECTED | Only the class itself and subclasses |
PRIVATE | Only within the class |
Examples
1. Define and Use a Simple Class
" DefinitionCLASS 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.
" ImplementationCLASS lcl_counter IMPLEMENTATION. METHOD increment. mv_count = mv_count + 1. ENDMETHOD.
METHOD get_value. rv_value = mv_count. ENDMETHOD.ENDCLASS.
" UsageSTART-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: 22. 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.
" UsageDATA: lo_person TYPE REF TO lcl_person.
" Create object with constructor parameterslo_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.
" UsageDATA: lo_calc TYPE REF TO lcl_calculator, lv_sum TYPE i, lv_quot TYPE f.
lo_calc = NEW #( ).
" RETURNING parameter: Functional methodlv_sum = lo_calc->add( iv_a = 5 iv_b = 3 ).WRITE: / 'Sum:', lv_sum.
" EXPORTING parameterlo_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 calllv_id2 = lcl_id_generator=>get_next_id( ).
WRITE: / 'ID 1:', lv_id1. " 1WRITE: / 'ID 2:', lv_id2. " 25. Inheritance
With INHERITING FROM, a class can inherit from another:
" Base classCLASS 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 classCLASS 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.
" UsageDATA: 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 doors6. 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.
" UsageDATA: 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( ). " SoundWRITE: / 'Dog:', lo_dog->speak( ). " Woof!Method Parameter Types
| Type | Description | Syntax |
|---|---|---|
IMPORTING | Input parameter | IMPORTING iv_param TYPE type |
EXPORTING | Output parameter | EXPORTING ev_param TYPE type |
CHANGING | Input and output | CHANGING cv_param TYPE type |
RETURNING | Return value (functional) | RETURNING VALUE(rv_param) TYPE type |
RAISING | Possible exceptions | RAISING cx_exception |
Object Creation
DATA: lo_obj TYPE REF TO lcl_myclass.
" Classic syntaxCREATE OBJECT lo_obj.
" With parametersCREATE OBJECT lo_obj EXPORTING iv_param = 'Value'.
" Modern syntax (from 7.40)lo_obj = NEW #( ).lo_obj = NEW #( iv_param = 'Value' ).
" Inline declarationDATA(lo_obj2) = NEW lcl_myclass( iv_param = 'Value' ).Global vs. Local Classes
| Type | Definition | Usage |
|---|---|---|
| Local | In program with CLASS ... DEFINITION | Only in the same program |
| Global | In 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
INTERFACEinstead of inheritance. - Handle errors with
TRY...CATCHand exceptions. - Prefer the modern syntax
NEW #( )for object creation. - Global classes (SE24) are reusable and testable.