OOP ABAP Part 5: Instance Methods, Static Methods and Constructors
Understand instance vs static components, the instance CONSTRUCTOR and CLASS CONSTRUCTOR, when each runs, and practical patterns such as validating objects at creation and caching customizing in static attributes.
Explanation
📌 KEY POINTS
✅ Instance components (METHODS, DATA) belong to each object; static components (CLASS-METHODS, CLASS-DATA) belong to the class.
✅ CONSTRUCTOR runs once per CREATE OBJECT; CLASS_CONSTRUCTOR runs once per session before the class is first used.
✅ Constructors ensure objects start in a valid state — or raise an exception.
⚠️ Heavy use of static methods hides dependencies and makes code hard to test.
━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE
Part 1 introduced constructors briefly. Now we look at instance vs static design in detail.
━━━━━━━━━━━━━━━━━━━━
▶ 1. INSTANCE COMPONENTS
- Work with object state (attributes of this object).
- Called with lo_obj->method( ).
- Each object has its own copy of instance attributes.
━━━━━━━━━━━━━━━━━━━━
▶ 2. STATIC COMPONENTS
- CLASS-DATA exists once for all objects; CLASS-METHODS are called with zcl_x=>method( ) without an object.
- Static methods can only access static attributes directly.
- Good for: stateless helpers (conversion, formatting), factory methods (Part 8), caches of customizing read once.
━━━━━━━━━━━━━━━━━━━━
▶ 3. THE INSTANCE CONSTRUCTOR
METHODS constructor IMPORTING iv_carrid TYPE s_carr_id … RAISING zcx_flight_error.
- Runs automatically during CREATE OBJECT, before the reference is returned.
- Only IMPORTING parameters (and exceptions).
- Use it to set mandatory attributes and validate input. If it raises an exception, the object is not created.
- In subclasses: the constructor must call super->constructor( ) before accessing instance components.
━━━━━━━━━━━━━━━━━━━━
▶ 4. THE STATIC CONSTRUCTOR
CLASS-METHODS class_constructor.
- No parameters; runs automatically once per internal session, before the first access to the class (object creation or static access).
- Use for one-time initialization, e.g. reading a small customizing table into CLASS-DATA.
━━━━━━━━━━━━━━━━━━━━
▶ 5. EXECUTION ORDER (INHERITANCE)
Class constructors of superclass then subclass (once), then for each CREATE OBJECT the subclass constructor, which calls super->constructor( ) first.
━━━━━━━━━━━━━━━━━━━━
▶ 6. INSTANCE OR STATIC?
- Needs state or dependencies (DAO) → instance.
- Might need a different implementation in tests → instance behind an interface.
- Pure function without state (format date) → static is acceptable.
- 💡 Clean ABAP recommends instance methods by default.
━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP
- Run the code example: observe the order of class_constructor and constructor outputs.
- Create an object for a non-existing flight and catch the constructor exception.
- Check that the carrier cache is filled only once.
✅ CHECKPOINT: you know when constructors run and choose instance vs static on purpose.
Code example
REPORT zoop_constructors. CLASS lcl_flight DEFINITION. PUBLIC SECTION. CLASS-METHODS: class_constructor, " once per session get_carrier_name IMPORTING iv_carrid TYPE s_carr_id RETURNING VALUE(rv_name) TYPE s_carrname. METHODS: constructor IMPORTING iv_carrid TYPE s_carr_id iv_connid TYPE s_conn_id iv_fldate TYPE s_date RAISING cx_sy_itab_line_not_found, get_free_seats RETURNING VALUE(rv_free) TYPE i. PRIVATE SECTION. CLASS-DATA gt_carriers TYPE HASHED TABLE OF scarr WITH UNIQUE KEY carrid. " static cache DATA ms_flight TYPE sflight. " instance stateENDCLASS. CLASS lcl_flight IMPLEMENTATION. METHOD class_constructor. SELECT * FROM scarr INTO TABLE gt_carriers. " read customizing once WRITE: / 'class_constructor: carriers cached'. ENDMETHOD. METHOD get_carrier_name. DATA ls_carr TYPE scarr. READ TABLE gt_carriers INTO ls_carr WITH TABLE KEY carrid = iv_carrid. IF sy-subrc = 0. rv_name = ls_carr-carrname. ENDIF. ENDMETHOD. METHOD constructor. WRITE: / 'constructor for', iv_carrid, iv_connid. SELECT SINGLE * FROM sflight INTO ms_flight WHERE carrid = iv_carrid AND connid = iv_connid AND fldate = iv_fldate. IF sy-subrc <> 0. RAISE EXCEPTION TYPE cx_sy_itab_line_not_found. " object is NOT created ENDIF. ENDMETHOD. METHOD get_free_seats. rv_free = ms_flight-seatsmax - ms_flight-seatsocc. ENDMETHOD.ENDCLASS. DATA: lo_flight TYPE REF TO lcl_flight, ls_sfl TYPE sflight, lv_name TYPE s_carrname, lv_free TYPE i. START-OF-SELECTION.* Static call - no object needed; triggers class_constructor first lv_name = lcl_flight=>get_carrier_name( 'LH' ). WRITE: / 'Carrier:', lv_name. SELECT SINGLE * FROM sflight INTO ls_sfl WHERE carrid = 'LH'. * Instance creation - constructor validates TRY. CREATE OBJECT lo_flight EXPORTING iv_carrid = ls_sfl-carrid iv_connid = ls_sfl-connid iv_fldate = ls_sfl-fldate. lv_free = lo_flight->get_free_seats( ). WRITE: / 'Free seats:', lv_free. CATCH cx_sy_itab_line_not_found. WRITE: / 'Flight not found'. ENDTRY. TRY. CREATE OBJECT lo_flight EXPORTING iv_carrid = 'XX' iv_connid = '0000' iv_fldate = sy-datum. CATCH cx_sy_itab_line_not_found. WRITE: / 'Invalid flight - object not created'. " class_constructor not repeated ENDTRY. * In a subclass constructor:* METHOD constructor.* super->constructor( iv_carrid = iv_carrid iv_connid = iv_connid iv_fldate = iv_fldate ).* " then subclass-specific initialisation* ENDMETHOD.Real project scenario
A utility class read the plant customizing table in a static method on every call. In a program processing 80,000 material documents it executed 80,000 identical SELECTs.
Moving the read into CLASS_CONSTRUCTOR with a hashed CLASS-DATA cache made the table load once per session. Later, for unit testing, the team replaced the static cache with an instance DAO injected via constructor, keeping the one-time read inside the DAO.
Common mistakes
- Creating objects without validation, leaving them half-initialized.
- Forgetting super->constructor( ) in subclass constructors.
- Static methods with hidden SELECTs everywhere (untestable).
- Expecting CLASS_CONSTRUCTOR to take parameters.
- Large data in static attributes that is never refreshed.
Best practices
- Validate mandatory data in the constructor; raise exceptions for invalid input.
- Prefer instance methods; use static for stateless helpers and factories.
- Use CLASS_CONSTRUCTOR for small one-time initializations.
- Keep constructors light (no heavy processing).
- Inject dependencies via constructor parameters.
Interview angle
Questions: "Constructor vs class constructor?", "When use static methods?", "Order of constructors in inheritance?"
Strong answer: instance constructor runs at each CREATE OBJECT, only IMPORTING parameters, can raise exceptions to prevent creation; class constructor runs once per session before first use, no parameters; superclass class constructors first; subclass constructor must call super->constructor; static methods for stateless helpers/factories, instance methods for state and testability.
Practice this lesson
Quick check
1. A pricing class keeps the sales organization in a static attribute. What happens when two sales orgs are processed in one program run?
2. When does CLASS_CONSTRUCTOR run?
3. Which parameters can an instance CONSTRUCTOR have?
Interview questions
1. Explain the difference between the instance constructor and the static constructor in ABAP OO. When is each executed, and when would you use each?
Answer it in your own words first, then compare.
2. Compare static methods and instance methods. When should you use each, and what are the implications for state management and testability?
Answer it in your own words first, then compare.
Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.
More lessons in this topic
- OOP ABAP Part 1: Classes, Objects, Attributes and Methods
- OOP ABAP Part 10: OOP in S/4HANA, RAP and Clean Core
- OOP ABAP Part 2: Local Classes vs Global Classes
- OOP ABAP Part 3: Inheritance, Interfaces and Polymorphism
- OOP ABAP Part 4: Class-Based Exceptions
- OOP ABAP Part 6: Encapsulation and Visibility — PUBLIC, PROTECTED, PRIVATE
- OOP ABAP Part 7: Composition vs Inheritance
- OOP ABAP Part 8: Interfaces and Factory Methods