From 6926ca4f3bdbb61433c568bffe000815796e4e89 Mon Sep 17 00:00:00 2001 From: danrega <16720986+danrega@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:46:58 +0100 Subject: [PATCH] Update --- 04_ABAP_Object_Orientation.md | 1055 +++++++++++++++++-- 06_Dynamic_Programming.md | 26 + 07_String_Processing.md | 4 +- 13_Program_Flow_Logic.md | 6 +- 22_Released_ABAP_Classes.md | 22 +- 26_ABAP_Dictionary.md | 6 +- src/zcl_demo_abap_cloud_excursion.clas.abap | 4 +- 7 files changed, 1025 insertions(+), 98 deletions(-) diff --git a/04_ABAP_Object_Orientation.md b/04_ABAP_Object_Orientation.md index d9e2d34..44f7e60 100644 --- a/04_ABAP_Object_Orientation.md +++ b/04_ABAP_Object_Orientation.md @@ -7,6 +7,7 @@ - [Creating Classes](#creating-classes) - [Creating a Global Class](#creating-a-global-class) - [Creating a Local Class](#creating-a-local-class) + - [Additions in the Class Declaration Part](#additions-in-the-class-declaration-part) - [Excursion: Class Pool and Include Programs](#excursion-class-pool-and-include-programs) - [Visibility of Components](#visibility-of-components) - [Creating the Visibility Sections](#creating-the-visibility-sections) @@ -38,7 +39,8 @@ - [Interfaces](#interfaces) - [Defining Interfaces](#defining-interfaces) - [Implementing Interfaces](#implementing-interfaces) - - [Interface Reference Variables and Accessing Objects](#interface-reference-variables-and-accessing-objects) + - [Additions Related to Interface Implementations](#additions-related-to-interface-implementations) + - [Interface Reference Variables, Accessing Objects and Components](#interface-reference-variables-accessing-objects-and-components) - [Excursion: Example Interface](#excursion-example-interface) - [Excursions](#excursions) - [Friendship](#friendship) @@ -48,6 +50,7 @@ - [Class-Based and Classic Exceptions](#class-based-and-classic-exceptions) - [ABAP Unit Tests](#abap-unit-tests) - [ABAP Doc Comments](#abap-doc-comments) + - [Escaping Characters](#escaping-characters) - [More Information](#more-information) - [Executable Examples](#executable-examples) @@ -149,19 +152,6 @@ CLASS global_class IMPLEMENTATION. ENDCLASS. ``` -> **💡 Note**
-> - The code snippet above shows the syntax to create a global class (indicated by `PUBLIC`), that is instantiable everywhere (indicated by `CREATE PUBLIC`) but that does not allow inheritance (indicated by `FINAL`, and which is covered further down). -> - There are more additions that can be specified. Find more information on the additions [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options.htm). -> - Examples: -> - `... CREATE PROTECTED.`: The class can only be instantiated in methods of its [subclasses](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm "Glossary Entry"), of the class itself, and of its [friends](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm "Glossary Entry"). -> - `... CREATE PRIVATE.`: The class can only be instantiated in methods of the class itself or of its friends. Hence, it cannot be instantiated as an inherited component of subclasses. -> - `... INHERITING FROM superclass ...`: As the name implies, it is used to inherit from a visible [superclass](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensuperclass_glosry.htm). If the addition is not specified, the created class implicitly inherits from the predefined empty, abstract class `object` (the root object). -> - `... ABSTRACT ...`: To define [abstract](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabstract_glosry.htm) classes. These classes cannot be instantiated. Abstract methods can only be implemented in [subclasses](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm). -> - `... [GLOBAL] FRIENDS class ...`: Used to define [friendships](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm) (also possible for interfaces). Friends of a class have unrestricted access to all components of that class. The `GLOBAL` addition can be used together with the `PUBLIC` addition and be specified with other global classes/interfaces following `GLOBAL FIRENDS`. Note: For local classes/interfaces, the addition [`LOCAL FRIENDS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_local_friends.htm) is available. -> - `... FOR TESTING ...`: For [ABAP Unit](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_unit_glosry.htm) tests. Find more information in the [ABAP Unit Tests](14_ABAP_Unit_Tests.md) cheat sheet. -> - `... FOR BEHAVIOR OF ...`: To define [ABAP behavior pools](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbehavior_pool_glosry.htm). Find more information in the [ABAP for RAP: Entity Manipulation Language (ABAP EML)](08_EML_ABAP_for_RAP.md) cheat sheet. -> - `... DEFINITION DEFERRED.`: Making a local class known in a program before the actual class definition. It is typically used in test classes of ABAP Unit. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_deferred.htm). -

⬆️ back to top

@@ -196,6 +186,181 @@ ENDCLASS.

⬆️ back to top

+ +#### Additions in the Class Declaration Part + +This section covers a selection of additions to declare classes. They are also covered in other sections below. Find more information on additions [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options.htm). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Addition Notes
+ +`PUBLIC` + + + +Creates a global class + +
+ +`FINAL` + + + +The class does not allow inheritance. + +
+ +`CREATE PUBLIC` + + + +The class is instantiable anywhere. + +
+ +`CREATE PROTECTED` + + + +The class can only be instantiated in methods of its [subclasses](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm "Glossary Entry"), of the class itself, and of its [friends](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm "Glossary Entry"). + +
+ +`CREATE PRIVATE` + + + +The class can only be instantiated in methods of the class itself or of its friends. Hence, it cannot be instantiated as an inherited component of subclasses. + +
+ +`INHERITING FROM superclass` + + + +As the name implies, it is used to inherit from a visible [superclass](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensuperclass_glosry.htm). If the addition is not specified, the created class implicitly inherits from the predefined empty, abstract class `object` (the root object). + +
+ +`ABSTRACT` + + + +To define [abstract](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabstract_glosry.htm) classes. These classes cannot be instantiated. These classes can contain both abstract methods and non-abstract methods. Abstract methods can only be implemented in [subclasses](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm) by redefinition. See a simple implementation example [here](#excursion-example-interface). + +
+ +`[GLOBAL|LOCAL] FRIENDS class` + + + +- Used to define [friendships](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm) (also possible for interfaces). Friends of a class have unrestricted access to all components of that class. +- `GLOBAL FRIENDS`: Used in global classes (together with the `PUBLIC` addition) to grant friendship to other global classes and interfaces +- `FRIENDS`: For local classes, e.g. local classes granting friendship to other local classes or the global class of the class pool +- `LOCAL FRIENDS`: Used for global classes to grant friendship to local classes and interfaces in its own class pool. However, it is a dedicated statement, as shown in the [Friendship](#friendship) section. + +
+ +`FOR TESTING` + + + +For [ABAP Unit](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_unit_glosry.htm) tests. Find more information in the [ABAP Unit Tests](14_ABAP_Unit_Tests.md) cheat sheet. + +
+ +`FOR BEHAVIOR OF` + + + +To define [ABAP behavior pools](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbehavior_pool_glosry.htm). Find more information in the [ABAP for RAP: Entity Manipulation Language (ABAP EML)](08_EML_ABAP_for_RAP.md) cheat sheet. + +
+ +`DEFINITION DEFERRED` + + + +Makes a local class known in a program before the actual class definition. It is typically used in test classes of ABAP Unit. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_deferred.htm). + +
+ + +

⬆️ back to top

+ + #### Excursion: Class Pool and Include Programs - A class pool is an ABAP program containing the definition of one global class (*Global Class* tab in ADT) @@ -3822,13 +3987,17 @@ Interfaces ...

⬆️ back to top

### Defining Interfaces -- Can be done either globally in the repository or locally in an ABAP program. + +- You can define global and local interfaces. +- Like global classes, global interfaces are defined using the `PUBLIC` addition. + ``` abap -INTERFACE intf. -"The addition PUBLIC is for global interfaces: -"INTERFACE intf_g PUBLIC. - +"The addition PUBLIC is for global interfaces +INTERFACE intf_global PUBLIC. +"Local interface +"INTERFACE intf_local. + DATA ... CLASS-DATA ... METHODS ... @@ -3839,71 +4008,76 @@ ENDINTERFACE.

⬆️ back to top

-### Implementing Interfaces +### Implementing Interfaces + - A class can implement multiple interfaces. -- Interfaces must be specified in the - declaration part of a class using the statement +- Interfaces must be specified in the declaration part of a class using the statement [`INTERFACES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces.htm). -- Since all interface components are public, you must include this - statement and the interfaces in the public visibility section of a class. When an interface is implemented in a class, all interface components are added to the other components of the class in the public visibility section. -- Interface components can be addressed using the [interface component - selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninterface_comp_selector_glosry.htm "Glossary Entry"): `... intf~comp ...`. -- You can specify alias names for the interface components using the statement [`ALIASES ... FOR ...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapaliases.htm). The components can then be addressed using the alias name. -- The class must implement the methods of all implemented interfaces in it unless the methods are flagged as abstract or final. You can adapt some interface components to requirements of your class. - - You can specify the additions [`ABSTRACT METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) followed by method names or [`ALL METHODS ABSTRACT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) for the `INTERFACES` statement in the declaration part of - classes. In this case, the class(es) need not - implement the methods of the interface. The implementation is then relevant for a subclass inheriting from a superclass that includes - such an interface declaration. Note that the whole class must be abstract. - - The additions [`FINAL METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) followed by method names or [`ALL METHODS FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) for the `INTERFACES` statement in the declaration part of classes flag the method(s) as final. -- In the interface, methods can mark their implementation as optional using the additions [`DEFAULT IGNORE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm) or [`DEFAULT FAIL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm). - - `DEFAULT IGNORE`: When a method with such a declaration is called without an implementation, it behaves as though no implementation exists. - - `DEFAULT FAIL`: If an unimplemented method is called, it triggers the `CX_SY_DYN_CALL_ILLEGAL_METHOD` exception. +- Since all interface components are public, you must include this statement and the interfaces in the public visibility section of a class. When an interface is implemented in a class, all interface components are added to the other components of the class in the public visibility section. +- Classes must implement the methods of all implemented interfaces in them unless ... + - methods are flagged as abstract or final (see next section). + - methods mark their implementation as optional using the additions [`DEFAULT IGNORE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm) or [`DEFAULT FAIL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm) (see next section). +- Interface components can be addressed using the [interface component selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninterface_comp_selector_glosry.htm "Glossary Entry"): `... intf~comp ...`. +- You can also include other interfaces in interfaces. +```abap +"Local interface in a CCIMP include +INTERFACE lif. -Syntax for using interfaces in classes: -``` abap -CLASS class DEFINITION. + DATA str TYPE string. + CLASS-DATA number TYPE i. + CONSTANTS const_number TYPE i VALUE 1. + "All of the following methods must be implemented in classes + "that implement the interface. + METHODS inst_meth IMPORTING num TYPE i. + CLASS-METHODS stat_meth RETURNING VALUE(result) TYPE string. + +ENDINTERFACE. + +"Local class in a CCIMP include implementing the interface +CLASS lcl DEFINITION. PUBLIC SECTION. - "Multiple interface implementations possible - INTERFACES intf. - ALIASES meth_alias FOR intf~some_method. + "Multiple interface implementations are possible + INTERFACES lif. ENDCLASS. -CLASS class IMPLEMENTATION. - METHOD intf~some_meth. "Method implementation using the original name - ... - ENDMETHOD. +CLASS lcl IMPLEMENTATION. - "Just for demo purposes: Method implementation using the alias name - "METHOD meth_alias. - " ... - "ENDMETHOD. - - ... -ENDCLASS. - -"----------------------- Abstract class ----------------------- -CLASS cl_super DEFINITION ABSTRACT. - PUBLIC SECTION. - INTERFACES intf ALL METHODS ABSTRACT. - ALIASES: - meth1 FOR intf~meth1, - meth2 FOR intf~meth2. -ENDCLASS. - -"Subclass inheriting from abstract class and implementing interface methods -CLASS cl_sub DEFINITION INHERITING FROM cl_super. - PUBLIC SECTION. - METHODS: - meth1 REDEFINITION, - meth2 REDEFINITION. -ENDCLASS. - -CLASS cl_sub IMPLEMENTATION. - METHOD meth1. + METHOD lif~inst_meth. + "Assuming lif~number is assigned a value somewhere. + DATA(addition) = num + lif~number. ... ENDMETHOD. - METHOD meth2. + + METHOD lif~stat_meth. + ... + ENDMETHOD. + +ENDCLASS. + +********************************************************************** +"Including interfaces in other interfaces + +INTERFACE lif2. + METHODS meth_of_lif2. + INTERFACES lif. +ENDINTERFACE. + +CLASS lcl2 DEFINITION. + PUBLIC SECTION. + INTERFACES lif2. +ENDCLASS. + +CLASS lcl2 IMPLEMENTATION. + METHOD lif2~meth_of_lif2. + ... + ENDMETHOD. + + METHOD lif~inst_meth. + ... + ENDMETHOD. + + METHOD lif~stat_meth. ... ENDMETHOD. ENDCLASS. @@ -3911,7 +4085,555 @@ ENDCLASS.

⬆️ back to top

-### Interface Reference Variables and Accessing Objects +### Additions Related to Interface Implementations + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Addition Notes
+ +[`ALIASES ... FOR ...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapaliases.htm) + + + +Specifies alias names for the interface components. The components can then be addressed using the alias name. + +
+ +```abap +"Local interface in a CCIMP include +INTERFACE lif. + METHODS some_method. + DATA some_string type string. +ENDINTERFACE. + +"Local class in a CCIMP include implementing the interface +CLASS lcl DEFINITION. + PUBLIC SECTION. + INTERFACES lif. + ALIASES meth FOR lif~some_method. + ALIASES str FOR lif~some_string. +ENDCLASS. + +CLASS lcl IMPLEMENTATION. + METHOD meth. + "This syntax is also possible: METHOD lif~some_method. + ... + DATA(string1) = str. + "This sytanx is also possible. However, when you have already addressed the component + "with the alias as in the assignment above, the following statement shows a syntax warning. + "DATA(string2) = lif~some_string. + ENDMETHOD. +ENDCLASS. +``` + +
+ +[`ABSTRACT METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) + + + +- Specifies instance methods as abstract. +- Multiple methods can be specified. +- The addition can only be used when the whole class is defined as abstract. + +
+ +``` abap +INTERFACE lif3. + METHODS meth1. + METHODS meth2. +ENDINTERFACE. + +"Local abstract class +"meth1 is specified as abstract method, meth2 is not. +"Therefore, only meth2 must be implemented. meth1 must +"be implemented by the subclasses. +CLASS lcl3 DEFINITION ABSTRACT. + PUBLIC SECTION. + INTERFACES lif3 ABSTRACT METHODS meth1. +ENDCLASS. + +CLASS lcl3 IMPLEMENTATION. + METHOD lif3~meth2. + ... + ENDMETHOD. +ENDCLASS. + +CLASS lcl4 DEFINITION INHERITING FROM lcl3. + PUBLIC SECTION. + METHODS lif3~meth1 REDEFINITION. +ENDCLASS. + +CLASS lcl4 IMPLEMENTATION. + METHOD lif3~meth1. + ... + ENDMETHOD. +ENDCLASS. +``` + +
+ +[`ALL METHODS ABSTRACT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) + + + +See above. With this addition, all methods are specified as abstract. + +
+ +``` abap +INTERFACE lif. + METHODS meth1. + METHODS meth2. +ENDINTERFACE. + +"Local abstract class +"All methods are specified as abstract methods. +"Therefore, all methods of the interface must be implemented +"by the subclasses. +CLASS lcl1 DEFINITION ABSTRACT. + PUBLIC SECTION. + INTERFACES lif ALL METHODS ABSTRACT. +ENDCLASS. + +CLASS lcl1 IMPLEMENTATION. + +ENDCLASS. + +CLASS lcl2 DEFINITION INHERITING FROM lcl1. + PUBLIC SECTION. + METHODS lif~meth1 REDEFINITION. + METHODS lif~meth2 REDEFINITION. +ENDCLASS. + +CLASS lcl2 IMPLEMENTATION. + METHOD lif~meth1. + ... + ENDMETHOD. + + METHOD lif~meth2. + ... + ENDMETHOD. + +ENDCLASS. +``` + +
+ +[`FINAL METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) + + + +Specifies methods as final so they cannot be further redefined. Multiple methods can be specified. + +
+ +```abap +INTERFACE lif. + METHODS meth1. + METHODS meth2. +ENDINTERFACE. + +"meth1 is specified as final method, meth2 is not. +"Therefore, only meth2 can be further redefined in subclasses. +CLASS lcl1 DEFINITION. + PUBLIC SECTION. + INTERFACES lif FINAL METHODS meth1. +ENDCLASS. + +CLASS lcl1 IMPLEMENTATION. + + METHOD lif~meth1. + ... + ENDMETHOD. + + METHOD lif~meth2. + ... + ENDMETHOD. + +ENDCLASS. + +CLASS lcl2 DEFINITION INHERITING FROM lcl1. + PUBLIC SECTION. + "meth1 cannot be redefined as it is declared as final in the superclass. + "METHODS lif~meth1 REDEFINITION. + METHODS lif~meth2 REDEFINITION. +ENDCLASS. + +CLASS lcl2 IMPLEMENTATION. + + METHOD lif~meth2. + ... + ENDMETHOD. + +ENDCLASS. +``` + +
+ +[`ALL METHODS FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) + + + +See above. With this addition, all methods are specified as final. + +
+ +``` abap +INTERFACE lif. + METHODS meth1. + METHODS meth2. +ENDINTERFACE. + +"All methods are specified as final. Therefore, they +"cannot be further redefined in subclasses. +CLASS lcl1 DEFINITION. + PUBLIC SECTION. + INTERFACES lif ALL METHODS FINAL. + METHODS meth3. +ENDCLASS. + +CLASS lcl1 IMPLEMENTATION. + + METHOD lif~meth1. + ... + ENDMETHOD. + + METHOD lif~meth2. + ... + ENDMETHOD. + + METHOD meth3. + ... + ENDMETHOD. + +ENDCLASS. + +CLASS lcl2 DEFINITION INHERITING FROM lcl1. + PUBLIC SECTION. + "meth1 and meth2 cannot be redefined. + "METHODS lif~meth1 REDEFINITION. + "METHODS lif~meth2 REDEFINITION. + METHODS meth3 REDEFINITION. +ENDCLASS. + +CLASS lcl2 IMPLEMENTATION. + + METHOD meth3. + ... + ENDMETHOD. + +ENDCLASS. +``` + +
+ +[`DATA VALUES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABAPINTERFACES_CLASS.html) + + + +- Used to assign start values for attributes +- Works in the style of `DATA ... VALUE ...` statements, e.g. `DATA number TYPE i VALUE 123`. + +
+ +``` abap +INTERFACE lif. + METHODS meth1 RETURNING VALUE(result) TYPE i. + DATA num1 TYPE i. + DATA num2 TYPE i. + CLASS-DATA num3 TYPE i. +ENDINTERFACE. + +CLASS lcl1 DEFINITION. + PUBLIC SECTION. + INTERFACES lif DATA VALUES num1 = 1 num2 = 3 num3 = 6. +ENDCLASS. + +CLASS lcl1 IMPLEMENTATION. + + METHOD lif~meth1. + result = lif~num1 + lif~num2 + lif~num3. + ENDMETHOD. + +ENDCLASS. + +CLASS lcl3 DEFINITION. + PUBLIC SECTION. + CLASS-METHODS meth. +ENDCLASS. + +CLASS lcl3 IMPLEMENTATION. + + METHOD meth. + "result: 10 + DATA(result) = NEW lcl1( )->lif~meth1( ). + ENDMETHOD. + +ENDCLASS. +``` + +
+ +[`PARTIALLY IMPLEMENTED`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABAPINTERFACES_PARTIALLY.html) + + + +- Relevant only for test classes. +- When you use the `PARTIALLY IMPLEMENTED` addition in test classes, you are not forced to implement all of the concrete non-optional methods. +- It is particularly useful for interfaces to implement test doubles, and not all methods are necessary. +- See the [ABAP Unit Tests](14_ABAP_Unit_Tests.md) cheat sheet. + +
+ +``` abap +"Test double class in a test include +CLASS ltd_test_double DEFINITION FOR TESTING. + PUBLIC SECTION. + INTERFACES some_intf PARTIALLY IMPLEMENTED. +ENDCLASS. + +CLASS ltd_test_double IMPLEMENTATION. + METHOD some_intf~some_meth. + ... + ENDMETHOD. +ENDCLASS. +``` + +
+ +[`DEFAULT IGNORE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm) + +
(addition used in the interface definition) + +
+ +- Marks the implementation of methods as optional +- Defines a default behavior when non-implemented methods are called. When a method with such a declaration is called without an implementation, it behaves as though no implementation exists. +- Can only be used in interfaces for instance and static methods (except constructors and test methods) + +
+ +``` abap +INTERFACE lif. + METHODS meth1 DEFAULT IGNORE. + METHODS meth2. +ENDINTERFACE. + +CLASS lcl1 DEFINITION. + PUBLIC SECTION. + INTERFACES lif. +ENDCLASS. + +"The class implementation does not include the optional +"implementation of lif~meth1. +CLASS lcl1 IMPLEMENTATION. + + METHOD lif~meth2. + ... + ENDMETHOD. + +ENDCLASS. + +CLASS lcl2 DEFINITION. + PUBLIC SECTION. + INTERFACES lif. +ENDCLASS. + +"The class implementation includes the optional +"implementation of lif~meth1. +CLASS lcl2 IMPLEMENTATION. + + METHOD lif~meth1. + ... + ENDMETHOD. + + METHOD lif~meth2. + ... + ENDMETHOD. + +ENDCLASS. + +CLASS lcl3 DEFINITION. + PUBLIC SECTION. + class-methods meth3. +ENDCLASS. + +"The class implementation includes the optional +"implementation of lif~meth1. +CLASS lcl3 IMPLEMENTATION. + + METHOD meth3. + DATA(oref1) = NEW lcl1( ). + DATA(oref2) = NEW lcl2( ). + + "Although not implemented, meth1 can be 'called' (i.e. + "it can be specified to be called). In this case, it is + "just like calling a method with empty implementation. + oref1->lif~meth1( ). + oref1->lif~meth2( ). + + "In this class, both methods are implemented. + oref2->lif~meth1( ). + oref2->lif~meth2( ). + + ENDMETHOD. + +ENDCLASS. +``` + +
+ +[`DEFAULT FAIL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm) + +
(addition used in the interface definition) + +
+ +See above. The behavior with this addition is that when an unimplemented method is called, the `CX_SY_DYN_CALL_ILLEGAL_METHOD` exception is raised. + +
+ +``` abap +INTERFACE lif. + METHODS meth1 DEFAULT FAIL. + METHODS meth2. +ENDINTERFACE. + +CLASS lcl1 DEFINITION. + PUBLIC SECTION. + INTERFACES lif. +ENDCLASS. + +"The class implementation does not include the optional +"implementation of lif~meth1. +CLASS lcl1 IMPLEMENTATION. + + METHOD lif~meth2. + ... + ENDMETHOD. + +ENDCLASS. + +CLASS lcl2 DEFINITION. + PUBLIC SECTION. + INTERFACES lif. +ENDCLASS. + +"The class implementation includes the optional +"implementation of lif~meth1. +CLASS lcl2 IMPLEMENTATION. + + METHOD lif~meth1. + ... + ENDMETHOD. + + METHOD lif~meth2. + ... + ENDMETHOD. + +ENDCLASS. + +CLASS lcl3 DEFINITION. + PUBLIC SECTION. + CLASS-METHODS meth3. +ENDCLASS. + +"The class implementation includes the optional +"implementation of lif~meth1. +CLASS lcl3 IMPLEMENTATION. + + METHOD meth3. + DATA(oref1) = NEW lcl1( ). + DATA(oref2) = NEW lcl2( ). + + "Although not implemented, meth1 can be 'called' (i.e. + "it can be specified to be called). + "However, with the DEFAULT FAIL addition, an exception is + "raised. + TRY. + oref1->lif~meth1( ). + CATCH cx_sy_dyn_call_illegal_method INTO DATA(error). + DATA(error_text) = error->get_text( ). + ENDTRY. + oref1->lif~meth2( ). + + "In this class, both methods are implemented. + oref2->lif~meth1( ). + oref2->lif~meth2( ). + + ENDMETHOD. + +ENDCLASS. +``` + +
+ + +

⬆️ back to top

+ +### Interface Reference Variables, Accessing Objects and Components - Addressing an object happens via an object reference variable with reference to a class. - An interface variable can contain references to objects of classes that implement the corresponding interface. @@ -3931,6 +4653,7 @@ Addressing interface components: ``` abap +"----------------------- Syntax patterns ----------------------- "Addressing instance interface components using interface reference variable DATA i_ref TYPE REF TO intf. @@ -3976,6 +4699,105 @@ i_ref = NEW class( ). ... intf=>const ... ``` +Example using local interfaces and classes + +```abap +INTERFACE lif. + METHODS inst_meth. + CLASS-METHODS stat_meth. + TYPES c1 TYPE c LENGTH 1. + DATA inst_num TYPE i. + CLASS-DATA stat_str TYPE string. + CONSTANTS const TYPE string VALUE `ABAP`. +ENDINTERFACE. + +CLASS lcl1 DEFINITION. + PUBLIC SECTION. + INTERFACES lif. +ENDCLASS. + +CLASS lcl1 IMPLEMENTATION. + + METHOD lif~inst_meth. + ... + ENDMETHOD. + + METHOD lif~stat_meth. + ... + ENDMETHOD. + +ENDCLASS. + +"This class demonstrates addressing interface components +CLASS lcl2 DEFINITION. + PUBLIC SECTION. + CLASS-METHODS meth. + DATA flag TYPE lif=>c1. +ENDCLASS. + +CLASS lcl2 IMPLEMENTATION. + + METHOD meth. + + "Addressing instance interface components using interface reference variable + "Interface reference variable + DATA i_ref TYPE REF TO lif. + "Object reference variable + DATA cl_ref TYPE REF TO lcl1. + + "Creating an instance of a class that implements the interface lif + cl_ref = NEW #( ). + + "If the class lcl1 implements the interface lif, + "the class reference variable cl_ref can be assigned + "to the interface reference variable i_ref. + "The reference in i_ref then points to the same object + "as the reference in cl_ref. + i_ref = cl_ref. + + "This can also be done directly, i. e. directly creating an object to + "which the interface reference variable points + DATA i_ref2 TYPE REF TO lif. + i_ref2 = NEW lcl1( ). + + "Instance interface method via interface reference variable + i_ref->inst_meth( ). + + "Instance interface attribute via interface reference variable + DATA(a) = i_ref->inst_num. + + "Addressing instance components using the class reference variable + "is also possible but it is not the recommended way. + cl_ref->lif~inst_meth( ). + DATA(b) = cl_ref->lif~inst_num. + + "Addressing static interface components + "The class name and => can be dropped if the method is called in the + "same class that implements the interface. + lcl1=>lif~stat_meth( ). + DATA(c) = lcl1=>lif~stat_str. + + "Note: Static interface components can be called via reference variables, too. + i_ref->stat_meth( ). + DATA(d) = i_ref->stat_str. + cl_ref->lif~stat_meth( ). + + "Constants + "A constant can be addressed using the options mentioned above. + "Plus, it can be addressed using the following pattern + DATA(e) = lif=>const. + DATA(f) = i_ref->const. + DATA(g) = cl_ref->lif~const. + + "Types + DATA h TYPE lif=>c1. + "Referring to attributes in the interface + DATA i LIKE lif=>const. + ENDMETHOD. + +ENDCLASS. +``` +

⬆️ back to top

### Excursion: Example Interface @@ -4413,10 +5235,9 @@ SET HANDLER handler3. > - Most examples are structured for easy exploration using simple, self-contained ABAP classes (i.e. only 1 class pool including local classes instead of multiple global classes) as follows: > - Global class: > - Includes the `if_oo_adt_classrun` interface to run the class with F9 in ADT. -> - Serves as a *vehicle* for demonstrating the design pattern. Only the declarations and implementations in the CCIMP include are relevant for the for conceptual considerations. +> - Serves as a *vehicle* for demonstrating the design pattern. Only the declarations and implementations in the CCIMP include are relevant for the conceptual considerations. > - CCIMP include (Local Types tab in ADT): > - Contains various local classes (some also include interfaces) to demonstrate design patterns, allowing quick copying and pasting without creating multiple global classes. -> - In some examples, note the use of the `DEFERRED` addition to class definitions, and not using the `PUBLIC` addition in all class definitions as they are local classes. Expand the following sections for further descriptions and example code. To try the examples, create a demo class named `zcl_demo_abap` and paste the code into it (*Global Class* and *Local Types* tabs in ADT). After activation, choose *F9* in ADT to execute the class. The examples are set up to display output in the console. @@ -7166,6 +7987,86 @@ ENDCLASS.

⬆️ back to top

+### Escaping Characters + +- You may stumble on [`!` characters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENNAMES_ESCAPING.html) specified before operands. +- They are used to distinguish the operand's name from ABAP words. +- When compiling ABAP programs, the specifications with the escape character are not considered as ABAP words. +- When executing the programs, the escape characters are ignored. + +The following nonsensical example shows various specifications with the escape character that emphasize in the program that the operands are not to be confused with ABAP words. These specifications are not mandatory in the example. The example only addresses escape characters you may stumble on in ABAP code. + +```abap +CLASS zcl_demo_abap DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + INTERFACES if_oo_adt_classrun. + + DATA num TYPE i. + CLASS-DATA default TYPE i VALUE 1. + METHODS meth1 IMPORTING !num TYPE i. + METHODS !methods IMPORTING !raising TYPE i OPTIONAL + !optional TYPE i + !exporting TYPE i + EXPORTING !importing TYPE i + !changing TYPE i + CHANGING !default TYPE i. + + PROTECTED SECTION. + PRIVATE SECTION. + +ENDCLASS. + +CLASS zcl_demo_abap IMPLEMENTATION. + + METHOD if_oo_adt_classrun~main. + meth1( 1 ). + + DATA !exporting TYPE i. + DATA !changing TYPE i. + methods( + EXPORTING + raising = 1 + optional = 5 + exporting = 10 + IMPORTING + importing = !exporting + changing = !changing + CHANGING + default = !default + ). + + ENDMETHOD. + METHOD meth1. + DATA(a) = num. + DATA(b) = me->num. + DATA(c) = !num. + + me->num = num. + me->num = !num. + ENDMETHOD. + + METHOD methods. + + !importing = !raising + !optional. + !changing = !exporting. + !default += 1. + + importing = raising + optional. + changing = exporting. + default += 1. + + ENDMETHOD. + +ENDCLASS. +``` + +

⬆️ back to top

+ + ## More Information You can check the subtopics of diff --git a/06_Dynamic_Programming.md b/06_Dynamic_Programming.md index dd59c0f..e9db5a3 100644 --- a/06_Dynamic_Programming.md +++ b/06_Dynamic_Programming.md @@ -29,6 +29,7 @@ - [Dynamic Specifications in Statements for Processing Internal Tables](#dynamic-specifications-in-statements-for-processing-internal-tables) - [Dynamic ABAP SQL Statements](#dynamic-abap-sql-statements) - [Dynamic Method Calls](#dynamic-method-calls) + - [Dynamic Function Module Calls](#dynamic-function-module-calls) - [Dynamic ABAP EML Statements](#dynamic-abap-eml-statements) - [Dynamic Formatting Option Specifications in String Templates](#dynamic-formatting-option-specifications-in-string-templates) - [Dynamic Parameter List in EXPORT and IMPORT Statements](#dynamic-parameter-list-in-export-and-import-statements) @@ -2621,6 +2622,31 @@ ENDCLASS.

⬆️ back to top

+### Dynamic Function Module Calls + +The following code snippet shows a dynamic function module call. Similar to dynamic method calls, a parameter table is used. It has the type `abap_func_parmbind_tab`. The function module name is specified as the value of a character-like data object. +See the section [Function Module Example](13_Program_Flow_Logic.md#function-module-example) in the [Program Flow Logic](13_Program_Flow_Logic.md) cheat sheet that includes the creation of a demo function module and static and dynamic function module calls. + +```abap +DATA(func_name) = 'Z_DEMO_ABAP_TEST_FUNC_M'. +DATA(ptab) = VALUE abap_func_parmbind_tab( ( name = 'NUM1' + kind = abap_func_exporting + value = NEW i( 3 ) ) + ( name = 'OPERATOR' + kind = abap_func_exporting + value = NEW string( `+` ) ) + ( name = 'NUM2' + kind = abap_func_exporting + value = NEW i( 5 ) ) + ( name = 'RESULT' + kind = abap_func_importing + value = NEW string( ) ) ). + +CALL FUNCTION func_name PARAMETER-TABLE ptab. +``` + +

⬆️ back to top

+ ### Dynamic ABAP EML Statements In the context of [RAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_rap_glosry.htm), [ABAP EML](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_eml_glosry.htm) statements are available with dynamic forms. diff --git a/07_String_Processing.md b/07_String_Processing.md index a136440..a8711d5 100644 --- a/07_String_Processing.md +++ b/07_String_Processing.md @@ -125,12 +125,12 @@ The following code snippet shows a global class implementing the interface `if_o - The literals can be (but should not according to the [programming guidelines on literals (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenliterals_guidl.htm)) used like constants of these types in [operand positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm). They should be only used for start values when declaring [named data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennamed_data_object_glosry.htm). ```abap -CLASS zcl_some_test_class DEFINITION PUBLIC FINAL CREATE PUBLIC. +CLASS zcl_demo_abap_class DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES if_oo_adt_classrun. ENDCLASS. -CLASS zcl_some_test_class IMPLEMENTATION. +CLASS zcl_demo_abap_class IMPLEMENTATION. METHOD if_oo_adt_classrun~main. out->write( `I am a text string literal` ). "text string literal of type string out->write( 'I am a text field literal' ). "text field literal of type c diff --git a/13_Program_Flow_Logic.md b/13_Program_Flow_Logic.md index d3bce5d..a10fc48 100644 --- a/13_Program_Flow_Logic.md +++ b/13_Program_Flow_Logic.md @@ -23,7 +23,7 @@ - [Special Function Modules in Standard ABAP](#special-function-modules-in-standard-abap) - [Subroutines in Standard ABAP](#subroutines-in-standard-abap) - [Excursion: RETURN](#excursion-return) - - [Interrupting the Program Execution](#interrupting-the-program-execution) + - [Interrupting the Program Execution with WAIT UP TO Statements](#interrupting-the-program-execution-with-wait-up-to-statements) - [Exceptions and Runtime Errors](#exceptions-and-runtime-errors) - [Executable Example](#executable-example) @@ -558,7 +558,7 @@ Further keywords for defining loops are as follows. They are not dealt with here ### Methods of Classes -In modern ABAP programs, only methods should be implemented (instead of [function modules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunction_module_glosry.htm) and [subroutines](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubroutine_glosry.htm) in most cases). +In modern ABAP programs, classes and methods are the way to go for modularization purposes (instead of [function modules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunction_module_glosry.htm) and [subroutines](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubroutine_glosry.htm) in most cases; the latter is only available in Standard ABAP). Note that methods and calling methods are described in the context of the [ABAP Object Orientation cheat sheet](04_ABAP_Object_Orientation.md). Find more information and examples there.

⬆️ back to top

@@ -898,7 +898,7 @@ ENDCLASS.

⬆️ back to top

-## Interrupting the Program Execution +## Interrupting the Program Execution with WAIT UP TO Statements Using [`WAIT UP TO`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapwait_up_to.htm) statements, you can interrupt the program execution by a specified number of seconds. diff --git a/22_Released_ABAP_Classes.md b/22_Released_ABAP_Classes.md index 24d185e..b6c3611 100644 --- a/22_Released_ABAP_Classes.md +++ b/22_Released_ABAP_Classes.md @@ -1387,19 +1387,19 @@ DATA(low_timestamp) = utclong_current( ). "utclong_add: Using the built-in function to create a UTC time stamp and "adding time values DATA(high_timestamp) = utclong_add( val = low_timestamp - days = 1 - hours = 2 - minutes = 3 - seconds = 4 ). + days = 1 + hours = 2 + minutes = 3 + seconds = 4 ). "diff: Calculating time differences "In the example, the returned values correspond to the ones added above. cl_abap_utclong=>diff( EXPORTING high = high_timestamp low = low_timestamp - IMPORTING days = DATA(days) - hours = DATA(hours) - minutes = DATA(minutes) - seconds = DATA(seconds) ). + IMPORTING days = DATA(days) + hours = DATA(hours) + minutes = DATA(minutes) + seconds = DATA(seconds) ). "read: Reading a time stamp from a string DATA(ts) = |{ utclong_current( ) TIMESTAMP = ENVIRONMENT TIMEZONE = 'UTC' }|. @@ -1811,13 +1811,13 @@ DATA: BEGIN OF s1, a TYPE i, b TYPE c LENGTH 3, c TYPE c LENGTH 5, - END OF s1. + END OF s1. DATA: BEGIN OF s2, a TYPE i, b TYPE c LENGTH 3, d TYPE string, - END OF s2. + END OF s2. "Populating structures s1 = VALUE #( a = 1 b = 'aaa' c = 'bbbbb' ). @@ -2704,7 +2704,7 @@ DATA(sub_acc_id) = ten->get_subaccount_id( )->as_string( ). CX_* -Exception classes are special classes, usually starting with the name CX_*, that serve as the basis for catchable exceptions. When an exception is raised, an object of such an exception class is created. There are several predefined exception classes. Find more information in the cheat sheet about program flow logic. +Exception classes are special classes, usually starting with the name CX_*, that serve as the basis for catchable exceptions. When an exception is raised, an object of such an exception class is created. There are several predefined exception classes. Find more information in the [Exceptions and Runtime Errors](27_Exceptions.md) cheat sheet.

``` abap diff --git a/26_ABAP_Dictionary.md b/26_ABAP_Dictionary.md index 98974cc..676c156 100644 --- a/26_ABAP_Dictionary.md +++ b/26_ABAP_Dictionary.md @@ -22,7 +22,7 @@ - [Excursions](#excursions) - [Built-in Database Functions](#built-in-database-functions) - [Finding Released Repository Objects in the System](#finding-released-repository-objects-in-the-system) - - [Creating Repository Objects Programmatically with XCO](#creating-repository-objects-programmatically-with-xco) + - [Retrieving Repository Objects Information and Creating Repository Object Programmatically with XCO](#retrieving-repository-objects-information-and-creating-repository-object-programmatically-with-xco) - [More Information](#more-information) - [Executable Example](#executable-example) @@ -735,9 +735,9 @@ SELECT ReleasedObjectType, ReleasedObjectName, ReleaseState

⬆️ back to top

-### Creating Repository Objects Programmatically with XCO +### Retrieving Repository Objects Information and Creating Repository Object Programmatically with XCO -Using the [XCO library](https://help.sap.com/docs/btp/sap-business-technology-platform/generation-apis), you can create ABAP repository objects programmatically. The executable example ([zcl_demo_abap_cloud_excursion](src/zcl_demo_abap_cloud_excursion.clas.abap)) of the [ABAP for Cloud Development](19_ABAP_for_Cloud_Development.md) cheat sheet includes demo code snippets. For more information, refer to the [documentation](https://help.sap.com/docs/btp/sap-business-technology-platform/generation-apis). +Using the [XCO library](https://help.sap.com/docs/btp/sap-business-technology-platform/generation-apis), you can create retrieve ABAP repository objects information and create the objects programmatically. The executable example ([zcl_demo_abap_cloud_excursion](src/zcl_demo_abap_cloud_excursion.clas.abap)) of the [ABAP for Cloud Development](19_ABAP_for_Cloud_Development.md) cheat sheet includes demo code snippets. The [Released ABAP Classes](22_Released_ABAP_Classes.md) cheat sheet also includes a small selection of code snippets in that context. For more information, refer to the [documentation](https://help.sap.com/docs/btp/sap-business-technology-platform/generation-apis).

⬆️ back to top

diff --git a/src/zcl_demo_abap_cloud_excursion.clas.abap b/src/zcl_demo_abap_cloud_excursion.clas.abap index 8cbd4ca..ecbb0c2 100644 --- a/src/zcl_demo_abap_cloud_excursion.clas.abap +++ b/src/zcl_demo_abap_cloud_excursion.clas.abap @@ -1,4 +1,4 @@ -"!

AMDP
Excursions into ABAP for Cloud Development

+"!

Excursions into ABAP for Cloud Development

"! "!

The example class demonstrates released APIs and libraries with the restricted "! ABAP language version.
@@ -431,7 +431,7 @@ CLASS zcl_demo_abap_cloud_excursion IMPLEMENTATION. DATA(a4_del_cl) = a2_content-delivery_class->value. DATA(a5_data_maint) = a2_content-data_maintenance->if_xco_printable~get_text( )->get_lines( )->join( )->value. "Getting all fields of the database table - "The handler is further processed. In the example, only the field names are retreived. + "The handler is further processed. In the example, only the field names are retrieved. DATA(a6_fields) = db->fields->all->get( ). CLEAR str.