Learn SAP from the Experts | The SAP PRESS Blog

How Classes Are Defined and Used in ABAP Objects

Written by SAP PRESS | Mar 27, 2026 1:00:03 PM

Classes in ABAP Objects are declared using the CLASS statement block. This statement block is a wrapper of sorts, grouping all relevant class component declarations into two distinct sections.

  • Declaration section: This section specifies all the components defined within the class including attributes, methods, and events.
  • Implementation section: This section provides implementations (i.e., the source code) for the methods defined within the declaration section.

In this post, we’ll unpack the syntax used to build out these sections and fully specify class types. For the purposes of this introductory section, our focus will be on defining local classes (i.e., classes that are defined within ABAP report programs and function group includes).

 

It’s good to note that this same syntax applies to the definition of global class types as well. The primary difference in the caseof global classes is that you have a form-based editor in the Class Builder tool that spares you from manually typing out some of the declaration syntax.

 

Creating a Class

To define a new class type, you must declare it within a CLASS...DEFINITION...ENDCLASS statement block as shown in the listing below. This statement block makes up the aforementioned declaration section of the ABAP class definition. This section is used to declare the primary components that make up a class, such as attributes and methods.

 

CLASS {class_name} DEFINITION [class_options].

    PUBLIC SECTION.

        [components]

    PROTECTED SECTION.

        [components]

    PRIVATE SECTION.

        [components]

ENDCLASS.

 

If you look closely, you can see that the components of a class definition are organized into three distinct visibility sections: the PUBLIC SECTION, the PROTECTED SECTION, and the PRIVATE SECTION. Each of these visibility sections is optional, so it’s up to you as a developer to determine which components go where.

 

Besides the definition of the components that makeup the class’s interface, the next most important task in defining a class is coming up with a good and meaningful name for it. As trivial as it may sound, this task is often harder than it looks. Part of the challenge stems from the fact that ABAP only gives you 30 characters to work with. You must come up with a meaningful name that fits within the confines of the syntax shown here.

 

[{Namespace}|{Prefix}]CL_{Meaningful_Name}

 

The following listing shows how this class naming syntax is applied to the various class types that may exist within the ABAP Repository.

 

LCL_LOCAL_CLASS         "Local Customer Class

ZCL_GLOBAL_CLASS        "Global Customer Class

CL_ABAP_MATCHER         "SAP-Standard Class (no namespace)

/BOWDK/CL_STRING_UTILS  "3rd-Party Class w/Namespace Prefix

 

 

 

Component Declarations

As you’ve seen, the structure and makeup of a class is determined by its component definitions. Therefore, in this section, you’ll learn about the different component types that you can define within a class. Before you get started, though, you first need to understand how components are grouped from a scoping perspective. Within a class declaration, there are two different types of components.

Instance Components

Instance components, as the name suggests, are components that define the state and behavior of individual object instances. For example, an Employee class might have an instance attribute called id that uniquely identifies an employee within a company. Each instance of the Employee class maintains its own copy of the id attribute, which has a distinct value. Instance methods operate on these instance attributes to manipulate the object’s state and perform instance-specific tasks.

Class Components

Class components, on the other hand, are defined at the class level, meaning class components are shared across all object instances. Such components can come in handy in situations where you want to share data or expose utility functions on a wider scale. For example, in the Employee class scenario, you might use a class attribute called next_id to keep track of the next available employee ID number. This value could be used as a primitive number range object to assign the id instance attribute for newly created Employee objects.

 

In practice, most of the classes you define will contain few class components. After all, it’s hard to establish identity at the object level if all the data and/or functionality resides in global class components. However, you’ll see that class components come in handy in certain situations, such as dealing with complex object creation scenarios or finding a home for utility functions.

 

Class components are sometimes referred to as static components since they are statically defined and maintained at the class level. This is especially the case in other object-oriented languages such as Java or C#.

Internal Namespaces

Regardless of where you decide to define your components, it’s important to keep in mind that all component names within an ABAP Objects class belong to the same internal namespace. For example, it’s not possible to define an attribute and a method using the same name—even if they belong to different visibility sections. In the sections that follow, you’ll learn that the adoption of good naming conventions makes it easy to avoid such naming collisions.

Attributes

Attributes are essentially variables defined internally within a class or object. Attributes are defined in the same way that variables are defined in other ABAP programming modules. The primary difference in the case of classes is that you’re contending with different contexts.

 

To put these contexts into perspective, consider the LCL_CUSTOMER sample class in the next listing. Within this class definition, we’ve defined three different types of attributes:

  • Instance attributes: To define the properties that are unique to a particular customer instance, we’ve created several instance attributes such as mv_id, mv_customer_type, mv_name, and ms_ address. As you can see, these instance attributes are defined using the familiar DATA keyword. Here, you can choose from any valid ABAP data type including structure types, table types, reference types, or even other class types.
  • Class attributes: The sv_next_id attribute is an example of a class attribute. As you can see, the only real difference syntax-wise between class attributes and instance attributes is the use of the CLASS-DATA keyword in lieu of the typical DATA keyword.
  • Constants: In the PUBLIC SECTION of our customer class, we’ve also defined several constants to represent the different customer types modeled in our class: CO_PERSON_TYPE for individuals, CO_ORG_TYPE for organizations, and CO_GROUP_TYPE for customer groups. These constants are defined just like any other constant using the CONSTANTS keyword. However, in the case of class constants, what we’re really talking about is a specialized case of a class/static attribute (one that can’t be modified at runtime).

CLASS lcl_customer DEFINITION.

    PUBLIC SECTION.

        CONSTANTS: CO_PERSON_TYPE TYPE c VALUE '1',

                                      CO_ORG_TYPE TYPE c VALUE '2',

                   CO_GROUP_TYPE TYPE c VALUE '3'.

    PRIVATE SECTION.

        DATA: mv_id TYPE i,

              mv_customer_type TYPE c,

              mv_name TYPE string,

              ms_address TYPE adrc.

    CLASS-DATA: sv_next_id TYPE i.

ENDCLASS.

 

Though the ABAP compiler will generally allow you to define attributes with whatever name you prefer, we strongly recommend that you adopt a naming convention that makes it easier to identify the scope of a given attribute.

Methods

Methods are defined using either the METHODS statement for instance methods or the CLASS-METHODS statement for class methods. The syntax for both statement types is shown in the syntax diagram below. Here, you can see that a method definition consists of a method name, an optional parameter list, and an optional set of exceptions that might occur. For this introductory section, we’ll focus on the first two parts of a method definition.

 

{CLASS-}METHODS {method_name}

    [IMPORTING parameters]

    [EXPORTING parameters]

    [CHANGING parameters]

    [RETURNING VALUE(parameter)]

    [{RAISING}|{EXCEPTIONS}...].

 

As you can see, the first thing you specify in a method definition is the method’s name. Since methods define the behavior of classes, it’s important that you come up with meaningful names that intuitively describe the method’s purpose. Normally, it makes sense to prefix a method name with a strong action verb that describes the type of operation being performed. The sample class in this listing provides some examples of this convention.

 

CLASS lcl_date DEFINITION.

    PUBLIC SECTION.

        METHODS:

            add IMPORTING iv_days TYPE i,

            subtract IMPORTING iv_days TYPE i,

            get_day_of_week RETURNING VALUE(rv_day) TYPE string,

            ...

ENDCLASS.

 

After you come up with meaningful names for your methods, your next objective is to determine what sort of parameters (if any) the methods will need to perform their tasks. If you look at the syntax diagram from earlier, you can see that there are four different types of parameters that can be defined within a method’s parameter list. This table describes each of these parameter types in detail.

 

Parameter Type Description
Importing Importing parameters define the input parameters for a method. The values of an importing parameter cannot be modified inside the method implementation. 
Exporting Exporting parameters are input/output parameters that allow you to update or modify data within a method.
Changing Changing parameters are input/output parameters that allow you to update or modify data within a method.
Returning Returning parameters are used to define functional methods.

 

To distinguish between the various parameter types within a method definition, method parameters are normally prefixed according to the convention described in the following table. Here, the {Type} designator is once again used to differentiate between elementary data types (V), structure types (S), table types (T), and so on.

 

Parameter Type Naming Convention
Importing I{Type}_{Parameter_Name}
Exporting E{Type}_{Parameter_Name} 
Changing C{Type}_{Parameter_Name} 
Returning R{Type}_{Parameter_Name} 

 

Regardless of the parameter’s type, the syntax for declaring a parameter p1 is shown in the syntax diagram in the next listing. As you can see, this syntax provides you with several configuration options for defining a parameter:

  • The optional VALUE addition allows you to specify that a parameter will be passed by value instead of by reference. For more details on this concept, check out the upcoming text box.
  • You can use the TYPE addition to specify the parameter’s data type. The addition is used in this context in the exact same way it’s used to define normal variables or form parameters.
  • You can use the OPTIONAL addition to mark a parameter as optional. Such parameters can be omitted during method calls on the consumer side.
  • You can use the DEFAULT addition to specify a default value for a given parameter (which makes the parameter optional from a consumer perspective). The caller of the method can override this value as needed.

{ p1 | VALUE(p1)} TYPE type [OPTIONAL | {DEFAULT def1}]

Pass-by-Value versus Pass-by-Reference

At runtime, whenever a method that contains parameters is invoked, the calling program will pass parameters by matching up actual parameters (e.g., local variables in the calling program and literal values) in the method call with the formal parameters declared in the method signature. Here, parameters are passed in one of two ways: by reference (default behavior) or by value.

 

Pass-by-value semantics is enabled via the aforementioned VALUE addition. Performance- wise, pass-by-value implies that a copy of an actual parameter is created and passed to the method for consumption. As a result, changes made to value parameters inside the method only affect the copy; the contents of the variable used as the actual parameter are not disturbed in any way. This behavior is illustrated at the top of the figure below with the mapping of parameter a. Here, whenever the method is invoked, a copy of variable x is made and assigned to parameter a. As you might expect, this kind of operation can become rather expensive when you start dealing with large data objects.

 

 

Reference parameters, on the other hand, contain a reference (or pointer) to the actual parameter used in the method call. Therefore, changes made to reference parameters are reflected in the calling program. In our figure, this is illustrated in the mapping of parameter b. Here, if you were to change the value of parameter b inside the method, the change would be reflected in variable y in the calling program.

 

Since this behavior can potentially cause dangerous side effects, ABAP allows you to lock down reference parameters for editing inside methods by defining them as importing parameters. For example, if you define parameter b as an importing parameter, the compiler would complain if you try to modify its contents within the method body. In effect, importing parameters allow you to attain all the performance benefits of reference passing without the negative effects.

 

Collectively, a method’s name and parameter list make up the method’s signature. From the perspective of class consumers, method signatures determine the exact requirements for calling a particular method: which parameters to pass, the data types of the parameters being exchanged, and so on. As a method designer, it’s important that you get these details right so that your methods are intuitive and easy to use. To that end, here are some design points to consider when defining method signatures:

  • In general, keep the number of parameters being passed to or from methods to the bare minimum. You should assume that an object already has most of the information it needs (via its instance attributes) to perform a particular task, so you should only require a handful of parameters when defining a method.
  • Define methods to perform one task. Avoid defining methods such as copyDataAndWashCat().
  • When performing generic operations where specific data types don’t matter, incorporate the use of generic ABAP types so that the methods can be (re)used in a variety of contexts. For a list of available generic types, search for “generic ABAP types” in the ABAP Keyword Documentation.

Events

Besides the more common attributes and methods that you see in most object-oriented languages, ABAP Objects also allows you to define events that model certain types of occurrences within an object’s lifecycle. Once again, you can distinguish between instance events that occur within a specific object instance and class events that are defined at the class level.

 

The next listing contains the basic syntax used to define instance events and class events. The parameters defined for an event are used to pass additional information about the event to interested event handler methods. Since this is a one-way data exchange, you’re only allowed to define exporting parameters in an event definition. The syntax is pretty much identical to the syntax used to define exporting parameters in methods. The only difference in this case is that event parameters must be passed by value. Aside from the formally defined exporting parameters in an event definition, the system also supplies an implicit parameter called sender that contains a reference to the sending object (i.e., the object that raised the event).

 

EVENTS evt [EXPORTING parameters].

CLASS-EVENTS evt [EXPORTING parameters].

Types

You can define custom data types within a class using the ABAP TYPES statement. These types are defined at the class level and are therefore not specific to any object instance. You can use these custom types to define local variables within methods, method parameter types, and so on. It’s also possible to declare the use of global type pools defined within the ABAP Dictionary using the TYPE-POOLS statement.

 

The definition of class LCL_PERSON in the next listing demonstrates how types can be declared and used in a class definition. Here, we’ve defined a custom structure type called TY_NAME that’s being used to define the person’s ms_name attribute. The use of the TY_ prefix in this case is by convention: Class-defined types are normally defined using the naming convention TY_{Type_Name}.

 

CLASS lcl_person DEFINITION.

    PRIVATE SECTION.

        TYPES: BEGIN OF ty_name,

            first_name TYPE char40,

            middle_initial TYPE char1,

            last_name TYPE char40,

        END OF ty_name.

        TYPE-POOLS: szadr. "Business Address Services

 

        DATA: ms_name TYPE ty_name,

        ms_address    TYPE szadr_addr1_complete.

ENDCLASS.

 

If you look closely, you can also see how type groups from the ABAP Dictionary are declared using the TYPE-POOLS statement. In this case, the class has declared the use of the SZADR type group from the Business Address Services package. Once this declaration is in place, you can use types such as the SZADR_ADDR1_COMPLETE type in attribute definitions and method signatures.

 

Implementing Methods

Any time you define methods within the declaration section of a class, you need to provide implementations for them in the implementation section. Such implementations are provided using METHOD...ENDMETHOD statement blocks that are nested inside of a CLASS...IMPLEMENTATION...ENDCLASS statement block, as shown here.

 

CLASS lcl_date DEFINITION.

    ...

ENDCLASS.

 

CLASS lcl_date IMPLEMENTATION.

    METHOD add.

        mv_date = mv_date + iv_days.

    ENDMETHOD.

 

    METHOD subtract.

        mv_date = mv_date - iv_days.

    ENDMETHOD.

 

    METHOD get_day_of_week.

        "Implementation goes here..

    ENDMETHOD.

ENDCLASS.

 

As you can see, method implementations allow you to jump right into the code. There’s no need to provide any further details about the method context, since you’ve already defined its signature in the declaration section. Within the method processing block, you can implement the behavior of the class using regular ABAP statements in much the same way that you would implement subroutines and function modules from the procedural world.

 

Syntax Restrictions

If you’re coming to ABAP Objects from a procedural background, we should point out that there are a handful of ABAP language constructs that have been rendered obsolete/deprecated from within the object-oriented context. These changes came about as part of a language cleanup effort when SAP first introduced object-oriented extensions to ABAP. SAP saw an opportunity to do some internal housekeeping and ensure that deprecated language elements didn’t make their way into new ABAP Objects classes.

 

For the most part, developers following current best practices shouldn’t encounter these statements, as their use is generally frowned upon in any context. Still, if you’re not sure which statements have become deprecated over the years, don’t worry; the compiler will tell you if you’ve used one.

 

Variable Scoping Rules

Before we wrap up our discussion on method implementations, let’s take a moment to discuss variable scoping rules in an object-oriented context. Unlike procedural contexts, where the context is pretty cut-and-dry between global variables and local variables, method implementations get their hands on variables at several different scoping levels:

  • Class attributes that behave like global variables
  • Local variables whose scope is limited to the method that defines them
  • Instance variables that sit somewhere in the middle, defining the state of a given object instance

With these additional options in play, you should be careful when qualifying variables so that their usage is clear. This makes the code more readable and prevents you from accidentally hiding instance or class attributes behind method-local variables with the same name. As you can expect, hiding instance or class attributes within a method can have some nasty side effects. Fortunately, if you stick to the naming conventions outlined, this shouldn’t ever be a concern.

 

Learn ABAP with Rheinwerk Courses!

Ready to level up your ABAP skills? Explore the full range of our ABAP-focused online courses, from foundational programming to advanced RAP, CDS, AMDP, unit testing, and more. Each one is instructor-led (live and on-demand), includes recordings and slide decks, and is designed to give you practical take-away skills you can apply right away in your SAP landscape. Click on the banner below to get started!

 

 

Bringing it All Together

Understanding how classes are defined and used in ABAP Objects is foundational to writing clean, maintainable, and modern SAP applications. From the declaration and implementation sections to visibility levels, attributes, methods, parameter passing, events, and custom types, these building blocks give you the control and flexibility to model real-world business objects in a way that is intuitive and reusable across your SAP development projects.

 

Whether you're working with local classes inside an ABAP report program or building global class types in the Class Builder, mastering these fundamentals, along with best practices like consistent naming conventions, focused methods, and thoughtful visibility design, sets a strong foundation for exploring more advanced ABAP Objects concepts like inheritance, interfaces, and polymorphism.

 

Editor’s note: This post has been adapted from sections of the books Object-Oriented Programming with ABAP Objects by Jeffrey Boggess, Colby Hemond, James Wood, and Joseph Rupert. Jeffrey is an enterprise integration specialist at Bowdark Consulting focused on building seamless integrations between SAP, Azure, and Dataverse to solve complex business challenges and provide dependable solutions for clients. Colby is a senior technical consultant at Bowdark Consulting, where he is dedicated to bringing innovative ideas and solutions to clients and supporting them in their digital transformation. James is the founder and CEO of Bowdark Consulting, Inc., a consulting firm specializing in technology and custom development in the SAP landscape. Joseph is a senior data architect at Bowdark Consulting, Inc. with expertise in migrating complex SAP landscapes to cloud platforms, enabling scalable, secure, and high-performance data ecosystems.

 

This post was originally published 3/2026.