OOP Refresher — Interfaces, Abstract Classes, and the RAP Connection
Bridge your Classic ABAP OOP knowledge to RAP patterns. Learn how interfaces, abstract classes, and handler methods connect to RAP behavior implementations.
OOP Refresher — Interfaces, Abstract Classes, and the RAP Connection
What You'll Learn
- Why OOP is the foundation of RAP (not optional — mandatory)
- Interfaces in ABAP Cloud — the contract pattern
- Abstract classes and method templates
- How RAP behavior implementations use these OOP patterns
- A preview of what RAP handler classes look like
Why This Lesson Exists
In the Classic course, you learned OOP as one of many approaches. You could write a report without classes. You could use function modules instead of methods. OOP was a best practice, not a requirement.
In ABAP Cloud, OOP is the only way to write executable code. There are no reports (SE38), no function modules (SE37), no subroutines (FORM/ENDFORM). Everything is a class.
RAP takes this further. When you define a business object's behavior (validations, actions, determinations), the framework generates a class skeleton. You fill in the methods. The pattern is always the same: interface → class → method implementation.
Interfaces — The Contract
An interface defines WHAT a class can do without saying HOW:
INTERFACE zif_tm_calculator PUBLIC.
METHODS calculate_total
IMPORTING it_items TYPE ztm_soitem_tab
RETURNING VALUE(rv_total) TYPE ztm_amount.
METHODS apply_discount
IMPORTING iv_percentage TYPE decfloat34
CHANGING cv_amount TYPE ztm_amount.
ENDINTERFACE.
Any class that implements this interface MUST provide these methods:
CLASS zcl_tm_standard_calc DEFINITION PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES zif_tm_calculator.
ENDCLASS.
CLASS zcl_tm_standard_calc IMPLEMENTATION.
METHOD zif_tm_calculator~calculate_total.
rv_total = REDUCE ztm_amount(
INIT sum = CONV ztm_amount( 0 )
FOR ls_item IN it_items
NEXT sum = sum + ( ls_item-quantity * ls_item-price )
).
ENDMETHOD.
METHOD zif_tm_calculator~apply_discount.
cv_amount = cv_amount * ( 1 - iv_percentage / 100 ).
ENDMETHOD.
ENDCLASS.
Why this matters for RAP: RAP behavior implementations follow this exact pattern. The framework defines the interface (what methods you must implement), and you provide the logic.
Abstract Classes — Templates for Behavior
An abstract class provides partial implementation — some methods are concrete, others are left for subclasses:
CLASS zcl_tm_order_processor DEFINITION PUBLIC ABSTRACT
CREATE PUBLIC.
PUBLIC SECTION.
METHODS process_order FINAL
IMPORTING is_order TYPE ztm_salesorder
RAISING cx_tm_order_error.
PROTECTED SECTION.
" Subclasses MUST implement these
METHODS validate_order ABSTRACT
IMPORTING is_order TYPE ztm_salesorder
RAISING cx_tm_order_error.
METHODS calculate_shipping ABSTRACT
IMPORTING is_order TYPE ztm_salesorder
RETURNING VALUE(rv_cost) TYPE ztm_amount.
ENDCLASS.
CLASS zcl_tm_order_processor IMPLEMENTATION.
METHOD process_order.
" Template method pattern — the framework calls this,
" but validate_order and calculate_shipping are YOUR code
validate_order( is_order ).
DATA(lv_shipping) = calculate_shipping( is_order ).
" ... continue processing
ENDMETHOD.
ENDCLASS.
Why this matters for RAP: RAP handler classes follow the template method pattern. The framework calls your methods at specific lifecycle points (on save, on modify, before action). You implement the business logic; the framework handles the plumbing.
The RAP Connection — A Preview
Here's what a RAP behavior implementation class actually looks like. Don't worry about understanding every detail yet — we'll build this step by step in Module 3. The point is to see the OOP pattern:
" This class is GENERATED by the RAP framework
" You fill in the method bodies
CLASS lhc_salesorder DEFINITION INHERITING FROM
cl_abap_behavior_handler.
PRIVATE SECTION.
" These methods are called by the framework
" Their signatures are defined by RAP, not by you
METHODS validate_customer FOR VALIDATE ON SAVE
IMPORTING keys FOR SalesOrder~validateCustomer.
METHODS determine_total FOR DETERMINE ON MODIFY
IMPORTING keys FOR SalesOrder~determineTotal.
METHODS approve_order FOR MODIFY
IMPORTING keys FOR ACTION SalesOrder~approve
RESULT result.
ENDCLASS.
CLASS lhc_salesorder IMPLEMENTATION.
METHOD validate_customer.
" YOUR business logic here
" Read the order data using EML
READ ENTITIES OF ZI_TM_SalesOrder IN LOCAL MODE
ENTITY SalesOrder
FIELDS ( customer_id )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_orders).
LOOP AT lt_orders INTO DATA(ls_order).
IF ls_order-customer_id IS INITIAL.
APPEND VALUE #( %tky = ls_order-%tky ) TO failed-salesorder.
APPEND VALUE #( %tky = ls_order-%tky
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = |Customer ID is required| )
) TO reported-salesorder.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD determine_total.
" Auto-calculate order total from line items
" ... implementation in Lesson 19
ENDMETHOD.
METHOD approve_order.
" Change status to 'Approved'
" ... implementation in Lesson 20
ENDMETHOD.
ENDCLASS.
See the pattern?
- The class inherits from
cl_abap_behavior_handler(an abstract class from the framework) - The methods are defined by the framework (you don't choose the signatures)
- You implement the body — that's your business logic
- The framework calls your methods at the right time (on save, on modify, on action)
This is the interface/abstract-class/template-method pattern from OOP textbooks, applied at industrial scale.
Key OOP Patterns You'll Use in RAP
| OOP Pattern | Where It Appears in RAP |
|---|---|
| Interface implementation | Behavior handler implements framework-defined method signatures |
| Template method | Framework calls your validation/determination/action methods |
| Dependency injection | Test doubles replace real dependencies for unit testing |
| Factory method | Factory actions create new BO instances |
| Observer pattern | Determinations react to data changes (on modify triggers) |
Common Mistakes
- "I'll skip OOP and learn RAP directly" — RAP IS OOP. Every behavior implementation is a class. Every validation is a method. If interfaces and inheritance confuse you, go back to the Classic OOP lessons before continuing.
- Trying to use procedural code in behavior implementations — You can't write
PERFORMorCALL FUNCTIONinside RAP handler methods. Everything is a method call on a class. - Overcomplicating class hierarchies — RAP keeps it simple: one handler class per entity, methods per behavior feature. Don't create deep inheritance trees. RAP doesn't need them.
- Ignoring the
LOCAL MODEkeyword — When reading data inside a handler, you useIN LOCAL MODEto bypass authorization (you're already inside the BO). Forgetting this causes authorization failures.
Key Takeaways
- In ABAP Cloud, OOP is mandatory — there's no procedural alternative.
- Interfaces define contracts (what methods must exist). RAP uses this pattern for behavior implementations.
- Abstract classes provide templates. RAP handler classes inherit from
cl_abap_behavior_handlerand implement framework-defined methods. - RAP behavior implementation = OOP template method pattern. The framework calls your methods; you provide the business logic.
- You don't need advanced OOP (multiple inheritance, design patterns beyond the basics). RAP keeps the class structure simple and predictable.
Next Lesson
With your environment set up, modern syntax mastered, and OOP refreshed, it's time to dive into CDS Views — the data modeling layer of modern ABAP. In Lesson 6, we'll create our first CDS view entity, modeling TechMart's product catalog. This is where Classic DDIC views get replaced by something far more powerful.