ABAP Object-Oriented Programming — Classes, Objects, Interfaces
Every SAP shop has one of these programs. Four thousand lines, a few hundred global variables, and a stack of FORM routines calling each other in an order nobody fully remembers anymore.
Change one field in one routine and something two screens away breaks. Nobody wants to touch it, so everybody works around it instead.
That is not a comment on whoever wrote it. It is what happens when every piece of logic can reach every piece of data, with no boundaries anywhere in between. ABAP Objects exists to fix exactly this problem.
Once the mental model of classes, objects and interfaces actually clicks, BAdIs, ALV OOP and the RAP framework stop looking like separate things you memorise, and start looking like the same handful of ideas, reused everywhere.
🔗 Related Reading
This post builds directly on the concepts in ABAP Fundamentals That Still Matter , and connects to ABAP RAP — What It Is, What It Replaces, and Why It Matters , since RAP behaviour implementations are written entirely in ABAP Objects. If FORM routines, function modules and internal tables still feel shaky, start there first.
Why ABAP went object-oriented
ABAP was procedural from the start. Reports, FORM routines and function modules, all sharing the same pool of global data. That worked fine when programs were small.
It stopped working as SAP applications got bigger. Nothing stopped a routine buried deep in a program from reaching out and quietly changing data that ten other routines also depended on. Bugs like that are brutal to trace, because the symptom and the cause can be hundreds of lines apart.
SAP introduced ABAP Objects in 1999, with R/3 release 4.6, as an object-oriented extension to the language.
It added classes, objects, inheritance and interfaces, without removing procedural ABAP. You can still write a FORM routine today. ABAP is a hybrid language on purpose, so decades of existing code did not need to be thrown away.
The point of the object-oriented extension was never to make ABAP look more like Java.
It was to let developers draw boundaries. A class owns its own data. Outside code cannot reach in and touch it directly, it has to ask through a method. That single rule is most of what makes object-oriented code easier to maintain than procedural code at scale.
📝 Note
ABAP still supports both styles side by side, and that is deliberate. You will find procedural and object-oriented ABAP in the same system, sometimes in the same program. The problem is not mixing them, it is mixing them carelessly inside the same object, which the Clean ABAP guidelines specifically warn against.
Classes and objects — the blueprint and the instance
A class is a blueprint. It describes what data an object of that type will hold, and what it can do. It is not the thing itself.
An object is what you get when you instantiate that blueprint. Create three objects from the same class and you get three separate instances, each with its own copy of the data, even though they all share the same behaviour defined once in the class.
Think of an invoice class. The blueprint says every invoice has an amount and a currency, and can calculate its own tax. Every actual invoice object has different values for amount and currency, but every one of them calculates tax the same way, because that logic lives in one place.
CLASS zcl_invoice DEFINITION.
PUBLIC SECTION.
METHODS calculate_tax
IMPORTING iv_amount TYPE p
RETURNING VALUE(rv_tax) TYPE p.
ENDCLASS.
CLASS zcl_invoice IMPLEMENTATION.
METHOD calculate_tax.
rv_tax = iv_amount * '0.20'.
ENDMETHOD.
ENDCLASS.
" Creating two separate objects from the same class
DATA(lo_invoice_1) = NEW zcl_invoice( ).
DATA(lo_invoice_2) = NEW zcl_invoice( ).
Classes are built in the Class Builder, transaction SE24, or through ABAP Development Tools in Eclipse for anything on a modern S/4HANA or BTP system. ADT is the current standard for new development, SE24 still works for classic on-premise systems.
Encapsulation — public, protected, private
This is the part that actually stops the four-thousand-line problem from happening again. Every component of a class sits in one of three visibility sections, and that section decides who is allowed to touch it.
| Section | What it means |
|---|---|
| PUBLIC SECTION | Visible to any caller, anywhere. This is the class’s contract with the outside world — keep it small and deliberate. |
| PROTECTED SECTION | Visible only to the class itself and any subclass that inherits from it. Used for internals a subclass needs to build on. |
| PRIVATE SECTION | Visible only inside the class itself. Nobody outside, not even a subclass, can touch it directly. |
Outside code cannot reach into a private attribute and change it directly, no matter how badly it wants to. It has to go through a public method, and that method can validate, log, or reject the change before it happens.
This is the entire fix for the debugging nightmare in the opening of this post. When a value changes unexpectedly, you are no longer searching the whole program. You are searching the small set of public methods actually allowed to change it.
✅ Best Practice
Default to PRIVATE for attributes, and expose behaviour through methods, not raw data through getters that just hand it back out. A method called calculate_tax tells the caller something about what the object does. A getter that just returns a private variable rarely does.
Inheritance — extending without duplicating
Inheritance lets one class, a subclass, take on everything defined in another class, the superclass, and then add or override specific parts of it.
A domestic invoice and an export invoice share almost everything. Same currency handling, same line item structure.
They differ only in how tax gets calculated. Inheritance lets the export invoice class inherit the shared behaviour and redefine only the one method that actually differs.
CLASS zcl_export_invoice DEFINITION
INHERITING FROM zcl_invoice.
PUBLIC SECTION.
METHODS calculate_tax REDEFINITION.
ENDCLASS.
CLASS zcl_export_invoice IMPLEMENTATION.
METHOD calculate_tax.
" Export invoices are zero-rated
rv_tax = 0.
ENDMETHOD.
ENDCLASS.
ABAP Objects supports single inheritance only. A class can have exactly one direct superclass, not several. That sounds like a limitation, and it is one, but it is a deliberate one — it keeps the inheritance tree simple enough to actually reason about.
Here is the honest part most introductions skip. SAP’s own Clean ABAP style guide recommends favouring composition over inheritance, not the other way round. Deep inheritance hierarchies get brittle fast — change something in a superclass and you can break subclasses three levels down without realising it.
📌 Key Takeaway
Inheritance is for a genuine “is-a” relationship — an export invoice is an invoice. If you are reaching for inheritance purely to reuse some code, composition, one object holding a reference to another, is usually the safer choice, and it is what SAP’s own guidelines recommend by default.
Interfaces and polymorphism — one contract, many shapes
An interface defines a contract, a list of methods a class promises to implement, without saying anything about how. The class fills in the actual logic.
A class can implement as many interfaces as it needs, even though it can only inherit from one superclass. That is the workaround ABAP uses instead of multiple inheritance, and in practice it is the more flexible tool anyway.
INTERFACE zif_taxable.
METHODS calculate_tax
IMPORTING iv_amount TYPE p
RETURNING VALUE(rv_tax) TYPE p.
ENDINTERFACE.
CLASS zcl_invoice DEFINITION.
PUBLIC SECTION.
INTERFACES zif_taxable.
ENDCLASS.
Polymorphism is what interfaces unlock. A method that accepts a reference to zif_taxable does not need to know or care whether it received an invoice, a purchase order, or something built two years from now that nobody has written yet. As long as it implements calculate_tax, the calling code works unchanged.
This is what makes interfaces the preferred route to polymorphism in ABAP, over deep inheritance trees. SAP’s own ABAP Keyword Documentation says as much directly, if your main goal is polymorphism, interfaces are usually the better solution.
💡 Practical Tip
Naming convention matters more than it looks. A ZIF_ or YIF_ prefix on an interface name is not just cosmetic, it tells the next developer instantly that they are looking at a contract, not an implementation.
Where this actually shows up in your SAP work
This stops being theory the moment you touch three things almost every ABAP developer runs into: BAdIs, ALV OOP, and RAP.
BAdIs are interfaces in disguise
A Business Add-In is SAP’s object-oriented answer to the old-style user exit. SAP defines an interface at a fixed enhancement spot in standard code. You write an implementing class that implements that interface, and SAP calls your method at runtime.
Multiple implementations can coexist, each filtered to different conditions, because it is all built on the same interface-and-polymorphism pattern covered above. Once you see a BAdI as “an interface someone else defined, that I implement,” the whole mechanism stops feeling mysterious.
ALV OOP replaced REUSE_ALV_GRID_DISPLAY
The classic function module REUSE_ALV_GRID_DISPLAY still runs, but the object-oriented ALV, built around the class CL_GUI_ALV_GRID, gives you far more control over layout, events and toolbar behaviour, because you are working with an object that holds its own state between calls instead of passing everything through parameters every time.
RAP is ABAP Objects, end to end
This is the one worth sitting with. In the ABAP RESTful Application Programming Model, the actual business logic for create, update and delete operations lives in a behaviour implementation class. That class is an ordinary ABAP Objects class, following the same encapsulation, interface and composition principles covered in this post.
If RAP feels intimidating from a distance, it is usually because the CDS and behaviour definition layers get all the attention. Underneath, the class doing the actual work is built from exactly the four ideas in this post.
⚠️ Warning
Do not mix procedural and object-oriented styles inside the same object. A class with a method that behaves differently depending on some external global state is the worst of both worlds — you lose the predictability procedural code has and the isolation object orientation is supposed to give you.
At a glance — ABAP Objects
| Concept | One-line summary |
|---|---|
| ABAP Objects | The object-oriented extension to ABAP, introduced in 1999 with R/3 release 4.6 |
| Class | The blueprint — defines the attributes and methods an object of that type will have |
| Object | An instance of a class, created at runtime, with its own independent copy of the data |
| Encapsulation | Hiding data behind PUBLIC, PROTECTED and PRIVATE sections so it can only change through controlled methods |
| Inheritance | A subclass takes on a superclass’s components and can redefine specific methods — ABAP supports single inheritance only |
| Interface | A contract of method signatures with no implementation — a class can implement any number of interfaces |
| Polymorphism | Code written against an interface works with any class that implements it, current or future |
| Composition over inheritance | SAP’s own Clean ABAP guidelines recommend this by default — safer than deep inheritance trees |
| BAdI | SAP’s enhancement framework built directly on the interface-and-implementing-class pattern |
| RAP behaviour implementation | An ordinary ABAP Objects class — the same principles in this post, applied to modern app development |
What to take away
ABAP Objects is not a syntax upgrade bolted onto the language you already know. It is a different question. Instead of asking “what should this routine do,” you start asking “whose responsibility is this data, and who should be allowed to touch it.”
Once that question becomes automatic, BAdIs, ALV OOP and RAP stop being three separate things to memorise. They are the same four ideas, classes, objects, encapsulation and interfaces, applied in three different corners of the same platform.
That four-thousand-line program from the start of this post did not go wrong because whoever wrote it lacked skill. It went wrong because procedural ABAP never asked the ownership question in the first place. ABAP Objects asks it by default, on every single class.
🔗 Related Reading
ABAP Fundamentals That Still Matter — the procedural foundation this post assumes you already have.
ABAP RAP — What It Is, What It Replaces, and Why It Matters — see the behaviour implementation class pattern from this post applied directly.
CDS Views and the VDM in SAP S/4HANA Explained — the data modelling layer that RAP’s object-oriented behaviour classes sit on top of.
SAP Security Roles and Authorisation — a different kind of layered mental model, built the same way this post built ABAP Objects, from the ground up.
Published on rakeshnarayan.com — Articles
URL: https://rakeshnarayan.com/articles/abap-object-oriented-programming-classes-objects-interfaces/



Did you enjoy this article?
Let me know — it takes one click.
0 Comments
Leave a Comment
Your comment has been submitted and will appear after review.