OOP ABAP
ABAP Developmentintermediate

OOP ABAP Part 3: Inheritance, Interfaces and Polymorphism

Key takeaway

Learn inheritance (INHERITING FROM, REDEFINITION, super- ), interfaces (INTERFACES, alias access), polymorphism through superclass and interface references, and up/down casts with ? = and CX SY MOVE CAST ERROR.

Explanation

📌 KEY POINTS
✅ Inheritance: a subclass (INHERITING FROM) reuses and can REDEFINE methods of its superclass.

✅ Interfaces define a contract; any class implementing it can be used through an interface reference.

✅ Polymorphism: the same call (lo_ref->calculate( )) runs different code depending on the object's actual class.

⚠️ Down-casting with ?= fails at runtime with CX_SY_MOVE_CAST_ERROR if the object is not of the target type.

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

Parts 1–2 covered single classes. Now classes work together through inheritance and interfaces.

━━━━━━━━━━━━━━━━━━━━
▶ 1. INHERITANCE

CLASS lcl_cargo_flight DEFINITION INHERITING FROM lcl_flight.

  • The subclass inherits public and protected components (not private).
  • METHODS get_price REDEFINITION — replaces the superclass implementation.
  • super->get_price( ) calls the superclass version inside the redefinition.
  • ABAP supports single inheritance only (one superclass).
  • FINAL classes cannot be inherited; FINAL methods cannot be redefined.

━━━━━━━━━━━━━━━━━━━━
▶ 2. ABSTRACT CLASSES

CLASS lcl_ticket DEFINITION ABSTRACT with METHODS get_price ABSTRACT.

  • Cannot be instantiated; subclasses must implement abstract methods.
  • Useful for a common frame with shared code plus mandatory specific parts.

━━━━━━━━━━━━━━━━━━━━
▶ 3. INTERFACES

INTERFACE lif_pricing. METHODS get_price RETURNING VALUE(rv_price) TYPE s_price. ENDINTERFACE.

  • A class declares INTERFACES lif_pricing and implements lif_pricing~get_price.
  • A class can implement many interfaces (the answer to single inheritance).
  • Global interfaces: ZIF_… in SE24. BAdIs are interfaces too.

━━━━━━━━━━━━━━━━━━━━
▶ 4. POLYMORPHISM

DATA lo_pricing TYPE REF TO lif_pricing.

lo_pricing = lo_economy. → lo_pricing->get_price( ) runs economy logic.

lo_pricing = lo_business. → the same call runs business logic.

Callers depend only on the interface, not on concrete classes.

━━━━━━━━━━━━━━━━━━━━
▶ 5. CASTING

  • Up-cast (widening): subclass/implementing object into superclass/interface reference — always allowed with =.
  • Down-cast (narrowing): lo_business ?= lo_pricing. — checked at runtime; wrap in TRY … CATCH cx_sy_move_cast_error.
  • 💡 Modern (7.50+): IS INSTANCE OF check and CAST #( ) operator.

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

  1. Run the code example: a table of lif_pricing references with different classes.
  2. Add a first-class pricing class — the loop needs no change.
  3. Try a wrong down-cast and catch the exception.

✅ CHECKPOINT: you can use inheritance and interfaces to let one piece of code work with many implementations.

Code example

ABAP Code
REPORT zoop_poly. * ===== Interface: the contract =====INTERFACE lif_pricing.  METHODS get_price RETURNING VALUE(rv_price) TYPE s_price.  METHODS get_class RETURNING VALUE(rv_class) TYPE char10.ENDINTERFACE. * ===== Abstract superclass with shared code =====CLASS lcl_ticket DEFINITION ABSTRACT.  PUBLIC SECTION.    INTERFACES lif_pricing ABSTRACT METHODS get_price get_class.    METHODS constructor IMPORTING iv_base TYPE s_price.  PROTECTED SECTION.    DATA mv_base TYPE s_price.           " visible in subclassesENDCLASS. CLASS lcl_ticket IMPLEMENTATION.  METHOD constructor.    mv_base = iv_base.  ENDMETHOD.ENDCLASS. * ===== Subclasses redefine the pricing =====CLASS lcl_economy DEFINITION INHERITING FROM lcl_ticket.  PUBLIC SECTION.    METHODS: lif_pricing~get_price REDEFINITION,             lif_pricing~get_class REDEFINITION.ENDCLASS. CLASS lcl_economy IMPLEMENTATION.  METHOD lif_pricing~get_price.    rv_price = mv_base.  ENDMETHOD.  METHOD lif_pricing~get_class.    rv_class = 'ECONOMY'.  ENDMETHOD.ENDCLASS. CLASS lcl_business DEFINITION INHERITING FROM lcl_ticket.  PUBLIC SECTION.    METHODS: lif_pricing~get_price REDEFINITION,             lif_pricing~get_class REDEFINITION,             get_lounge_access RETURNING VALUE(rv_ok) TYPE abap_bool.ENDCLASS. CLASS lcl_business IMPLEMENTATION.  METHOD lif_pricing~get_price.    rv_price = mv_base * 3.  ENDMETHOD.  METHOD lif_pricing~get_class.    rv_class = 'BUSINESS'.  ENDMETHOD.  METHOD get_lounge_access.    rv_ok = abap_true.  ENDMETHOD.ENDCLASS. * ===== Polymorphism: one loop, different behaviour =====DATA: lt_tickets  TYPE STANDARD TABLE OF REF TO lif_pricing,      lo_pricing  TYPE REF TO lif_pricing,      lo_economy  TYPE REF TO lcl_economy,      lo_business TYPE REF TO lcl_business,      lv_class    TYPE char10,      lv_price    TYPE s_price. START-OF-SELECTION.  CREATE OBJECT lo_economy  EXPORTING iv_base = '200'.  CREATE OBJECT lo_business EXPORTING iv_base = '200'.  APPEND lo_economy  TO lt_tickets.     " up-cast: always allowed  APPEND lo_business TO lt_tickets.   LOOP AT lt_tickets INTO lo_pricing.    lv_class = lo_pricing->get_class( ).    lv_price = lo_pricing->get_price( ). " actual class decides the code    WRITE: / lv_class, lv_price.  ENDLOOP. * ===== Down-cast: checked at runtime =====  LOOP AT lt_tickets INTO lo_pricing.    TRY.        lo_business ?= lo_pricing.        IF lo_business->get_lounge_access( ) = abap_true.          WRITE: / 'Lounge access granted'.        ENDIF.      CATCH cx_sy_move_cast_error.        WRITE: / 'Not a business ticket - no lounge'.    ENDTRY.  ENDLOOP.

Real project scenario

An output program printed three document types (invoice, credit memo, debit memo) with a large CASE statement repeated in five places. Adding a new "pro forma" type required changes in all five places and was missed twice.
The team defined an interface ZIF_DOC_OUTPUT with methods get_form_name and get_texts, implemented one class per document type and created the object via a factory. Adding the pro forma type now meant one new class; the calling code stayed untouched.

Common mistakes

  • Deep inheritance hierarchies for code reuse only.
  • Down-casting without TRY/CATCH or type check.
  • Forgetting that private components are not inherited.
  • Large CASE on type instead of polymorphism.
  • Redefining a method without calling super-> when the base behaviour is needed.

Best practices

  • Program against interfaces.
  • Use abstract classes for shared frame + mandatory parts.
  • Keep hierarchies shallow; prefer composition (Part 7).
  • Mark classes FINAL unless designed for inheritance.
  • Check before down-casts (IS INSTANCE OF or CATCH).

Interview angle

Questions: "Explain polymorphism in ABAP", "Abstract class vs interface?", "Up-cast vs down-cast?"
Strong answer: inheritance with INHERITING FROM and REDEFINITION (single inheritance); interfaces define contracts, a class can implement many; polymorphism = same call on a superclass/interface reference executes the actual class's implementation; up-cast always allowed, down-cast ?= checked at runtime (CX_SY_MOVE_CAST_ERROR); abstract classes can contain code, interfaces cannot (default ignore aside).

Practice this lesson

Quick check

1. Which call demonstrates polymorphism?

2. A class can inherit from:

3. SUPER->method() in a redefined method calls:

Interview questions

1. Explain the difference between an interface and an abstract class in ABAP Objects.

Answer it in your own words first, then compare.

2. Explain abstract classes and final classes in ABAP OO. When would you mark a class as ABSTRACT or FINAL, and what design constraints does this enforce?

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