OOP ABAP
ABAP Developmentbeginner

OOP ABAP Part 2: Local Classes vs Global Classes

Key takeaway

Know when to write a local class inside a program and when to create a global class in SE24/ADT — visibility, reuse, where-used lists, transport, test classes and the typical classic report structure with a local class.

Explanation

📌 KEY POINTS
✅ Local classes live inside one program (report, function group, class pool) and are visible only there.

✅ Global classes are repository objects (SE24 / SE80 / ADT) — reusable system-wide, with where-used list and own transport entry.

✅ Reusable business logic belongs in global classes; report-specific helpers can stay local.

⚠️ Copying a local class into several reports creates divergent copies.

━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE

Part 1 used a local class. Now: when is local fine and when must it be global?

━━━━━━━━━━━━━━━━━━━━
▶ 1. LOCAL CLASSES

  • Defined in the program source (often in an include like ZREPORT_CLS).
  • Visible only in that program; cannot be called from outside.
  • Typical use: a report's application class (lcl_report with methods get_data, process, display), event handlers for ALV, and local test classes.
  • Order matters: the DEFINITION must come before use; CLASS lcl_x DEFINITION DEFERRED allows referencing a class declared later.

━━━━━━━━━━━━━━━━━━━━
▶ 2. GLOBAL CLASSES

  • Created in SE24 (form-based or source-code editor), SE80 or ADT, names ZCL_…
  • Stored in a class pool; visible in all programs (subject to package rules).
  • Have a where-used list, documentation, versions and their own transport object.
  • Can contain local helper types/classes and local test classes in their includes.

━━━━━━━━━━━━━━━━━━━━
▶ 3. HOW TO DECIDE

  • Used by more than one program, a BAdI, RFC wrapper or OData service → global.
  • Only used by this report and specific to its screen/output → local.
  • Starts local but reuse appears → move it to global (don't copy).

━━━━━━━━━━━━━━━━━━━━
▶ 4. CLASSIC REPORT STRUCTURE WITH A LOCAL CLASS

Many modern classic reports look like this:

  • Selection screen in the main program.
  • lcl_report DEFINITION/IMPLEMENTATION in an include.
  • START-OF-SELECTION: CREATE OBJECT go_report. go_report->run( ).

This replaces the older pattern of many FORM routines while keeping the report shape (events, selection screen) familiar.

━━━━━━━━━━━━━━━━━━━━
▶ 5. GLOBAL CLASS IN SE24

  • Properties tab: instantiation (Public/Protected/Private), Final.
  • Attributes, Methods, Events tabs; Source code-based view shows the same as text.
  • Local Types / Local Test Classes buttons for internal helpers and ABAP Unit.

━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP

  1. Create report ZOOP_LOCAL with lcl_report (code example).
  2. Create global class ZCL_FLIGHT_UTIL in SE24 with a static method get_carrier_name.
  3. Call the global method from the local class and check the where-used list of ZCL_FLIGHT_UTIL.

💡 Modern: in ADT, global classes are edited as source; RAP behaviour pools are global classes whose logic lives in local handler classes.

✅ CHECKPOINT: you place new classes deliberately — local for report-specific code, global for reuse.

Code example

ABAP Code
REPORT zoop_local. PARAMETERS p_carr TYPE s_carr_id DEFAULT 'LH'. * ===== Local class: report-specific application logic =====CLASS lcl_report DEFINITION.  PUBLIC SECTION.    METHODS run.  PRIVATE SECTION.    DATA mt_flights TYPE STANDARD TABLE OF sflight.    METHODS: get_data,             display.ENDCLASS. CLASS lcl_report IMPLEMENTATION.  METHOD run.    get_data( ).    display( ).  ENDMETHOD.   METHOD get_data.    SELECT * FROM sflight INTO TABLE mt_flights WHERE carrid = p_carr.  ENDMETHOD.   METHOD display.    DATA: ls_flight TYPE sflight,          lv_name   TYPE s_carrname.*   Reusable logic comes from a GLOBAL class    lv_name = zcl_flight_util=>get_carrier_name( p_carr ).    WRITE: / 'Carrier:', lv_name.    LOOP AT mt_flights INTO ls_flight.      WRITE: / ls_flight-connid, ls_flight-fldate, ls_flight-seatsocc.    ENDLOOP.  ENDMETHOD.ENDCLASS. DATA go_report TYPE REF TO lcl_report. START-OF-SELECTION.  CREATE OBJECT go_report.  go_report->run( ). * ===== Global class ZCL_FLIGHT_UTIL (SE24, source-code view) =====* CLASS zcl_flight_util DEFINITION PUBLIC FINAL CREATE PUBLIC.*   PUBLIC SECTION.*     CLASS-METHODS get_carrier_name*       IMPORTING iv_carrid      TYPE s_carr_id*       RETURNING VALUE(rv_name) TYPE s_carrname.* ENDCLASS.** CLASS zcl_flight_util IMPLEMENTATION.*   METHOD get_carrier_name.*     SELECT SINGLE carrname FROM scarr INTO rv_name WHERE carrid = iv_carrid.*   ENDMETHOD.* ENDCLASS. * ===== Referencing a local class before its definition =====* CLASS lcl_handler DEFINITION DEFERRED.* DATA go_handler TYPE REF TO lcl_handler.

Real project scenario

Three reports each had a local class LCL_PRICE_CHECK copied from the first report. A tax rounding fix was applied in only one of them, and finance found different totals in month-end reports.
The team created global class ZCL_PRICE_CHECK, moved the logic and tests into it, and replaced the three local copies with calls. The where-used list now shows every consumer, and the next rounding change was a single transport.

Common mistakes

  • Copying local classes between programs.
  • Creating global classes for trivial report-only helpers.
  • Using a local class before its definition without DEFINITION DEFERRED.
  • Making global classes non-final and fully public by default.
  • Forgetting that local classes cannot be called from other programs.

Best practices

  • Global for reuse, local for report-specific code.
  • Use an application class (lcl_report) instead of many FORMs in new reports.
  • Mark global classes FINAL unless inheritance is intended.
  • Keep test classes with the code they test.
  • Move local classes to global when reuse appears.

Interview angle

Questions: "Difference between local and global classes?", "When would you use a local class?", "How do you structure a report with classes?"
Strong answer: local classes are defined in a program and visible only there; global classes are repository objects in SE24/ADT with where-used and transport; reuse → global, report-specific (lcl_report, ALV event handler, tests) → local; don't copy local classes; a report can keep its selection screen and events but delegate to an application class.

Practice this lesson

Quick check

1. An ALV event handler is used only by one report; a material validation rule is used by four programs. Best placement?

2. Which statement about global classes is TRUE?

3. A local class lcl_handler is used in a DATA declaration before its DEFINITION appears in the source. What is needed?

Interview questions

1. Explain the difference between a local class and a global class in ABAP OO. When would you use each, and what are the implications for maintainability and reusability?

Answer it in your own words first, then compare.

2. An ALV event handler is a local class in a report, while a material validation rule is needed by several programs. Where should each class live and why?

Answer it in your own words first, then compare.

Practice more with Interview AI →

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

Interview questions on this topic

Related SAP topics