This commit is contained in:
danrega
2024-06-12 17:08:57 +02:00
parent 1120480ac5
commit b65faccce0
7 changed files with 662 additions and 49 deletions

View File

@@ -13,7 +13,7 @@
- [Defining Components](#defining-components)
- [Class Attributes](#class-attributes)
- [Methods](#methods)
- [Method Parameter Interface](#method-parameter-interface)
- [Parameter Interface](#parameter-interface)
- [Constructors](#constructors)
- [Working with Objects and Components](#working-with-objects-and-components)
- [Declaring Reference Variables](#declaring-reference-variables)
@@ -23,6 +23,7 @@
- [Calling Methods](#calling-methods)
- [Method Chaining](#method-chaining)
- [Self-Reference me](#self-reference-me)
- [Example Class](#example-class)
- [Inheritance](#inheritance)
- [Additions: ABSTRACT and FINAL](#additions-abstract-and-final)
- [Redefining Methods](#redefining-methods)
@@ -93,13 +94,13 @@ You can either create local or global classes:
<table>
<tr>
<td><a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlocal_class_glosry.htm">Local classes</a></td>
<td><ul><li>can be defined within an <a href="[https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlocal_class_glosry.htm](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm)">ABAP program</a></li><li>can only be used in the ABAP program in which the class is defined</li></ul></td>
<td><ul><li>can be defined within an <a href="[https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlocal_class_glosry.htm](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm)">ABAP program</a> such as in the <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenccimp_glosry.htm">CCIMP include</a> of global classes (Local Types tab in ADT) or in executable programs ("reports"; in <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_abap_glosry.htm">Standard ABAP</a> only)</li><li>can only be used in the ABAP program in which the class is defined</li></ul></td>
</tr>
<tr>
<td><a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_class_glosry.htm">Global
classes</a></td>
<td><ul><li>are defined as
<a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_type_glosry.htm">global types</a>, i. e. they are visible as a repository object - in contrast to local classes. As a global type, they can be used - as the name implies - globally in other ABAP programs or global classes</li><li>are declared in <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_pool_glosry.htm">class pools</a> that can contain a <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenccimp_glosry.htm">CCIMP include</a> and other <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninclude_program_glosry.htm">include programs</a></li></ul> </td>
<a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_type_glosry.htm">global types</a>, i. e. they are visible as a repository object - in contrast to local classes. As a global type, they can be used - as the name implies - globally in other ABAP programs or global classes</li><li>are declared in <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_pool_glosry.htm">class pools</a> that contain a <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenccimp_glosry.htm">CCIMP include</a> and other <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninclude_program_glosry.htm">include programs</a></li></ul> </td>
</tr>
</table>
@@ -214,7 +215,7 @@ CLASS zcl_demo_test IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
"---- The method called uses type declarations in the CCDEF include ----
"---- The method called has formal parameters using type declarations from the CCDEF include ----
TRY.
DATA(result1) = calculate( num1 = 10 operator = '+' num2 = 4 ).
out->write( data = result1 name = `result1` ).
@@ -492,7 +493,7 @@ ENDCLASS.
You declare them using `METHODS` statements in a visibility
section. Note that you must create an instance of a class first before using instance methods.
#### Method Parameter Interface
#### Parameter Interface
In the simplest form, methods can have no parameter at all. Apart from that, methods can be defined with the following parameters:
@@ -501,7 +502,7 @@ In the simplest form, methods can have no parameter at all. Apart from that, met
|`IMPORTING`|Defines one or more input parameters to be imported by the method. |
|`EXPORTING`|Defines one or more output parameters to be exported by the method. |
|`CHANGING`|Defines one or more input or output parameters, i. e. that can be both imported and exported. |
|`RETURNING`|For [functional methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunctional_method_glosry.htm "Glossary Entry"), i. e. such methods have only one `RETURNING` parameter that can be defined. As an output parameter like the `EXPORTING` parameter, `RETURNING` parameters pass back values (note that the formal parameters of returning parameters must be passed by value as covered below). In contrast to `EXPORTING` for which multiple parameters can be specified, only one `RETURNING` parameter can be specified in a method. If you only need one output parameter, you can benefit from using a `RETURNING` parameter by shortening the method call and enabling method chaining. Another big plus is that such functional methods can, for example, be used in expressions. In case of standalone method calls, the returned value can be accessed using the addition `RECEIVING`. |
|`RETURNING`|For [functional methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunctional_method_glosry.htm "Glossary Entry"), i. e. such methods have only one `RETURNING` parameter that can be defined. As an output parameter like the `EXPORTING` parameter, `RETURNING` parameters pass back values (note that the formal parameters of returning parameters must be passed by value as covered below; the parameter must be [completely typed](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplete_typing_glosry.htm)). In contrast to `EXPORTING` for which multiple parameters can be specified, only one `RETURNING` parameter can be specified in a method. If you only need one output parameter, you can benefit from using a `RETURNING` parameter by shortening the method call and enabling method chaining. Another big plus is that such functional methods can, for example, be used in expressions. In case of standalone method calls, the returned value can be accessed using the addition `RECEIVING`. |
|`RAISING` | Used to declare the [class-based exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_based_exception_glosry.htm "Glossary Entry") that can be propagated from the method to the caller. |
@@ -573,14 +574,16 @@ In the simplest form, methods can have no parameter at all. Apart from that, met
instantiated and an instance is created.
- Can have `IMPORTING` parameters and raise exceptions.
Example for method definitions: The following snippet shows
**Example for method definitions**
The following snippet shows
multiple method definitions in the public section of a local class. Most of the formal
parameters of the demo methods below are defined by just using the
parameter name. This means passing by reference (returning parameters
require to be passed by value).
``` abap
CLASS local_class DEFINITION.
PUBLIC.
PUBLIC SECTION.
METHODS: inst_meth1, "instance methods
inst_meth2 IMPORTING a TYPE string,
@@ -963,6 +966,550 @@ ENDMETHOD.
<p align="right"><a href="#top">⬆️ back to top</a></p>
### Example Class
The commented example class below explores various aspects covered in the previous sections. You can create a demo class called `zcl_demo_test` and copy and paste the following code. Once activated, you can choose *F9* in ADT to run the class. The example is designed to display output in the console that shows the result of calling different methods.
```abap
CLASS zcl_demo_test DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
"------------------------ Attributes ------------------------
"Instance attribute
DATA: inst_attr TYPE utclong,
inst_string TYPE string.
"Static attribute
CLASS-DATA stat_attr TYPE utclong.
"Attribute with the READ-ONLY addition. It is also possible for instance
"attributes. Such an attribute can only be read from outside the class,
"not changed. Inside the class, it can be changed. This also applies to
"subclasses (note that the example class does not allow inheritance).
CLASS-DATA read_only_attr TYPE string VALUE `read only` READ-ONLY.
"------------------------ Methods ------------------------
"The parameter interfaces (signatures) of the methods are intended to
"demonstrate various syntax options described in the cheat sheet.
"Instance methods
METHODS:
"No parameter specified
inst_meth1,
"Single importing parameter
inst_meth2 IMPORTING ip TYPE string,
"Importing and exporting parameters
inst_meth3 IMPORTING ip1 TYPE i
ip2 TYPE i
EXPORTING ep TYPE i,
"Returning parameters
inst_meth4 RETURNING VALUE(ret) TYPE string,
inst_meth5 IMPORTING ip1 TYPE string
ip2 TYPE string
EXPORTING ep TYPE string
RETURNING VALUE(ret) TYPE string,
"Changing parameter
inst_meth6 CHANGING chg TYPE string,
"Raising exceptions
inst_meth7 IMPORTING ip1 TYPE i
ip2 TYPE i
RETURNING VALUE(ret) TYPE i
RAISING cx_sy_arithmetic_overflow,
inst_meth8 IMPORTING ip1 TYPE i
RETURNING VALUE(ret) TYPE string
RAISING cx_uuid_error,
"Instance constructor
"Instance constructors can optionally have importing parameters
"and raise exceptions.
constructor.
"Static methods
CLASS-METHODS:
"Options of formal parameter definitions
stat_meth1 IMPORTING REFERENCE(ip1) TYPE string "pass by reference (specifying REFERENCE(...) is optional)
ip2 TYPE string "pass by reference
VALUE(ip3) TYPE string "pass by value
RETURNING VALUE(ret) TYPE string, "pass by value (mandatory for returning parameters)
"OPTIONAL/DEFAULT additions
"Both additions denote that passing values is optional. DEFAULT: If not supplied,
"the default value specified is used.
stat_meth2 IMPORTING ip1 TYPE string DEFAULT `ABAP`
ip2 TYPE string OPTIONAL
RETURNING VALUE(ret) TYPE string_table,
"Generic types are possible for field symbols and method parameters
"All of the previous formal parameters are typed with complete types (e.g. type i).
"The following method includes several formal parameters typed with generic
"types. Find more information in the 'Data Types and Objects' cheat sheet.
"Note: Returning parameters must be completely typed.
stat_meth3 IMPORTING ip_data TYPE data "Any data type
ip_clike TYPE clike "Character-like data type (such as c, n, string, etc.)
ip_numeric TYPE numeric "Numeric type (such as i, p, decfloat34 etc.)
ip_any_table TYPE ANY TABLE "Any table type (standard, sorted, hashed)
RETURNING VALUE(ret) TYPE string, "No generic type possible for returning parameters
"Static constructor
"No parameters possible
class_constructor.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_demo_test IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
"Note:
"This is a self-contained example. Usually, you must create an instance
"of a class first before using instance methods - when calling methods
"from outside, e.g. from another class. Within the class itself, you can
"indeed call the instance methods without a prior instance creation.
"To demonstrate 'calls from external', an instance of the class is
"nevertheless created in the example.
"--------------- Constructors ---------------
"Instance constructor: Automatically called when a class is instantiated
"and an instance is created.
"Creating an instance of a class and accessing an instance attribute
"using the object component selector ->.
DATA(oref) = NEW zcl_demo_test( ).
out->write( data = oref->inst_attr name = `oref->inst_attr` ).
"Creating more instances
"The example is implemented in a way that an instance attribute
"is assigned a time stamp when the instance constructor is called.
"As instance constructors are called once for each instance, the
"inst_attr values differ.
DATA(oref2) = NEW zcl_demo_test( ).
out->write( data = oref2->inst_attr name = `oref2->inst_attr` ).
DATA(oref3) = NEW zcl_demo_test( ).
out->write( data = oref3->inst_attr name = `oref3->inst_attr` ).
"Static constructor: Automatically and immediately called once for each class
"when calling a class for the first time in an internal session (e.g. an instance
"is created or a component is used).
"The example is implemented in a way that a static attribute is assigned a time
"stamp when the static constructor is called. The class was called with creating
"an instance above, and so the static constructor was called once. There is no new
"time stamp assigment, no new calls of the static constructor in this internal session.
"Therefore, the value of stat_attr is the same.
"The access is done using the class name, the class component selector =>, and
"the attribute name.
out->write( data = zcl_demo_test=>stat_attr name = `zcl_demo_test=>stat_attr` ).
"Static attributes are also accessible via the object reference variable
out->write( data = oref->stat_attr name = `oref->stat_attr` ).
"Checking that the values of the instance attribute that is modified when calling
"the instance constructor differ from instance to instance.
IF ( oref3->inst_attr > oref2->inst_attr )
AND ( oref2->inst_attr > oref->inst_attr ).
out->write( `Instance attribute check: All values differ.` ).
ELSE.
out->write( `Instance attribute check: At least one check is not successful.` ).
ENDIF.
"Checking that the value of the static attribute that is modified when calling
"the static constructor is identical from instance to instance (it is only changed
"when the class is called for the first time).
IF ( oref3->stat_attr = oref2->stat_attr )
AND ( oref2->stat_attr = oref->stat_attr )
AND ( oref->stat_attr = zcl_demo_test=>stat_attr ).
out->write( `Static attribute check: All values are identical.` ).
ELSE.
out->write( `Static attribute check: At least one check is not successful.` ).
ENDIF.
"Excursion: See the note above. In the self-contained example, in this class itself, the
"components can be called without reference variable or providing the class name. The
"assumption in the following snippets of the example is that the class is called
"from outside and instances are created outside of the class, so the variable/class
"name are provided.
"The following access is possible in the same class (not outside of this class):
DATA(a) = inst_attr.
DATA(b) = stat_attr.
"The following is also possible inside the class (it the only option outside of
"this class):
DATA(c) = oref->inst_attr.
DATA(d) = zcl_demo_test=>stat_attr.
DATA(e) = oref->stat_attr.
"--------------- Method calls ---------------
"Calling instance methods
"Instance methods are called using the object component selector ->
"via reference variables.
"--- Method without parameters ---
oref->inst_meth1( ).
"To show an effect of the method call in the example, the method implementation
"simply includes the change of an instance attribute value.
out->write( data = oref->inst_string name = `oref->inst_string` ).
"Notes:
"- See the method implementation of inst_meth1. It shows that
" instance methods can access both static and instance attributes.
"- As mentioned above regarding the attributes, in the same class and
" in this example, you can call the methods directly (without via
" a reference variable).
inst_meth1( ).
"--- Methods that specify importing parameters ---
"Similar to the inst_meth1 method, the implementation includes the
"change of an instance attribute.
"Notes:
"- In the method call, the caller exports values to the
" method having importing parameters defined. Therefore, the addition
" EXPORTING is relevant for the caller.
"- If a method only specifies importing parameters, specifying EXPORTING
" is optional.
"- If a method only specifies a single importing parameter, specifying
" EXPORTING and the formal parameter name is optional.
"Method with a single importing parameter (the following three method
"calls are basically the same)
"Method call that specifies EXPORTING and the formal parameter name
oref->inst_meth2( EXPORTING ip = `hello` ).
out->write( data = oref->inst_string name = `oref->inst_string` ).
"Method call that specifies the formal parameter, without EXPORTING
oref->inst_meth2( ip = `world` ).
out->write( data = oref->inst_string name = `oref->inst_string` ).
"Method call that only includes the actual parameter
oref->inst_meth2( `ABAP` ).
out->write( data = oref->inst_string name = `oref->inst_string` ).
"--- Methods that specify exporting parameters ---
"For the method call, specify EXPORTING for importing parameters,
"and IMPORTING for exporting parameters.
"The method implementation performs a calculation. The calculation
"result is assigned to the exporting parameter. You can assign the
"value to a suitable data object.
DATA calc_result1 TYPE i.
oref->inst_meth3( EXPORTING ip1 = 5
ip2 = 3
IMPORTING ep = calc_result1 ).
out->write( data = calc_result1 name = `calc_result1` ).
"Inline declaration is also possible.
oref->inst_meth3( EXPORTING ip1 = 2
ip2 = 4
IMPORTING ep = DATA(calc_result2) ).
out->write( data = calc_result2 name = `calc_result2` ).
"--- Methods that specify returning parameters ---
DATA(result1) = oref->inst_meth4( ).
out->write( data = result1 name = `result1` ).
"The RECEIVING addition is available in standalone method
"calls only if methods are defined with a returning parameter.
"Inline declaration is also possible here.
oref->inst_meth4( RECEIVING ret = DATA(result2) ).
out->write( data = result2 name = `result2` ).
"The following example method specifies multiple parameters,
"among them 2 output parameters (exporting and reporting).
"Functional method call
"In a functional method call, inline declaration is not possible
"for 'ep'.
DATA str1 TYPE string.
DATA(str2) = oref->inst_meth5( EXPORTING ip1 = `AB`
ip2 = `AP`
IMPORTING ep = str1 ).
out->write( data = str1 name = `str1` ).
out->write( data = str2 name = `str2` ).
"Standalone method call (including inline declarations)
oref->inst_meth5( EXPORTING ip1 = `AB`
ip2 = `AP`
IMPORTING ep = DATA(str3)
RECEIVING ret = DATA(str4) ).
out->write( data = str3 name = `str3` ).
out->write( data = str4 name = `str4` ).
"Returning parameters enable ...
"... the use of method calls in other statements, for example,
"in logical expressions, instead of storing the method call
"result in an extra variable.
IF oref->inst_meth4( ) IS INITIAL.
out->write( `Initial` ).
ELSE.
out->write( `Not initial` ).
ENDIF.
"... method chaining to write more concise code and avoid
"declaring helper variables.
"The following example uses a class that creates random integers.
"The 'create' method has a returning parameter. It returns an
"instance of the class (an object reference) based on which
"more methods can be called. Using method chaining, you can
"do the following in one go.
DATA(inst) = cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
min = 1
max = 10 ).
DATA(random_integer1) = inst->get_next( ).
DATA(random_integer2) = cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
min = 1
max = 10 )->get_next( ).
out->write( data = random_integer1 name = `random_integer1` ).
out->write( data = random_integer2 name = `random_integer2` ).
"--- Method that specifies a changing parameter ---
"Changing parameters should be reserved for changing an existing
"local variable and value.
"The method implementation includes the demonstration of the
"self-reference 'me'. For this purpose, a data object is created
"in the method implementation that has the same name as a data
"object declared in the class's declaration part.
"Changing the value of the instance attribute with the same name
"as the local data object in the method implementation.
oref->inst_string = `TEST`.
DATA local_var TYPE string VALUE `hello`.
oref->inst_meth6( CHANGING chg = local_var ).
out->write( data = local_var name = `local_var` ).
"--- Methods that specify RAISING ---
"The following example method declares an exception of the category
"CX_DYNAMIC_CHECK. That is, the check is not performed until runtime.
"There is no syntax warning shown at compile time.
"The ipow function is included in the method implementation. The
"second example raises the exception.
"No TRY control structure, no syntax warning at compile. However,
"the calculation works.
DATA(power_res1) = oref->inst_meth7( ip1 = 5 ip2 = 2 ).
out->write( data = power_res1 name = `power_res1` ).
"The example raises the exception because the resulting number is too high.
"Not catching the exception results in a runtime error.
TRY.
DATA(power_res2) = oref->inst_meth7( ip1 = 10 ip2 = 10 ).
out->write( data = power_res2 name = `power_res2` ).
CATCH cx_sy_arithmetic_overflow.
out->write( `cx_sy_arithmetic_overflow was raised` ).
ENDTRY.
"The following example method declares an exception of the category
"CX_STATIC_CHECK. That is, it is statically checked. Without the
"TRY control structure and catching the exception, a syntax warning
"is displayed. And in the case of the example implementation,
"the exception is indeed raised. Not cathcing the exception results
"in a runtime error.
TRY.
DATA(test) = oref->inst_meth8( ip1 = 1 ).
out->write( data = test name = `test` ).
CATCH cx_uuid_error.
out->write( `cx_uuid_error was raised` ).
ENDTRY.
"A syntax warning is displayed for the following method call.
"DATA(test2) = oref->inst_meth8( ip1 = 1 ).
"Calling static methods
"The method definitions/implementations cover further aspects.
"--- Pass by reference/value ---
"The following example method emphasizes pass by reference and
"by value.
"Notes:
"- Returning parameters can only be declared with VALUE(...)
"- When passing by reference, the content of the data objects
" cannot be changed in the method implementation.
"- The method implementation includes that ...
" - attributes declared with READ-ONLY can be changed within
" the class they are declared.
" - static methods can only access static attributes.
DATA(res) = zcl_demo_test=>stat_meth1( ip1 = `a` "pass by reference (declaration with REFERENCE(...))
ip2 = `b` "pass by reference (without REFERENCE(...))
ip3 = `c` "pass by value (declaration with VALUE(...))
).
out->write( data = res name = `res` ).
"--- OPTIONAL/DEFAULT additions ---
"The method implementation includes the predicate expression IS SUPPLIED
"that checks whether a formal parameter is populated.
DATA(res_tab1) = zcl_demo_test=>stat_meth2( ip1 = `aaa` ip2 = `bbb` ).
out->write( data = res_tab1 name = `res_tab1` ).
DATA(res_tab2) = zcl_demo_test=>stat_meth2( ip1 = `ccc` ).
out->write( data = res_tab2 name = `res_tab2` ).
DATA(res_tab3) = zcl_demo_test=>stat_meth2( ip2 = `ddd` ).
out->write( data = res_tab3 name = `res_tab3` ).
DATA(res_tab4) = zcl_demo_test=>stat_meth2( ).
out->write( data = res_tab4 name = `res_tab4` ).
"--- Generically typed formal parameters ---
"In the following method calls, various data objects are
"assigned to formal parameters. Note that returning parameters
"must be completely typed.
"In the example, the value passed for parameter ip_clike (which is
"convertible to type string) is returned.
DATA(res_gen1) = zcl_demo_test=>stat_meth3( ip_data = VALUE string_table( ( `hi` ) ) "any data type
ip_clike = abap_true "Character-like data type (such as c, n, string, etc.)
ip_numeric = 1 "Numeric type (such as i, p, decfloat34 etc.)
ip_any_table = VALUE string_table( ( `ABAP` ) ) "Any table type (standard, sorted, hashed)
).
out->write( data = res_gen1 name = `res_gen1` ).
DATA(res_gen2) = zcl_demo_test=>stat_meth3( ip_data = 123
ip_clike = 'ABAP'
ip_numeric = CONV decfloat34( '1.23' )
ip_any_table = VALUE string_hashed_table( ( `hello` ) ( `world` ) )
).
out->write( data = res_gen2 name = `res_gen2` ).
ENDMETHOD.
METHOD class_constructor.
"Assigning the current UTC timestamp to a static attribute
stat_attr = utclong_current( ).
ENDMETHOD.
METHOD constructor.
"Assigning the current UTC timestamp to an instance attribute
inst_attr = utclong_current( ).
ENDMETHOD.
METHOD inst_meth1.
inst_string = `Changed in inst_meth1`.
"Instance methods can access both static and instance attributes.
DATA(a) = inst_attr.
DATA(b) = stat_attr.
ENDMETHOD.
METHOD inst_meth2.
inst_string = |Changed in inst_meth2. Content of passed string: { ip }|.
ENDMETHOD.
METHOD inst_meth3.
ep = ip1 + ip2.
ENDMETHOD.
METHOD inst_meth4.
ret = |This string was assigned to the returning parameter at { utclong_current( ) }|.
ENDMETHOD.
METHOD inst_meth5.
ep = |Strings '{ ip1 }' and '{ ip2 }' were assigned to the exporting parameter at { utclong_current( ) }|.
ret = |Strings '{ ip1 }' and '{ ip2 }' were assigned to the returning parameter at { utclong_current( ) }|.
ENDMETHOD.
METHOD inst_meth6.
"Demonstrating the self-reference 'me'
"Its use is optional. The following data object intentionally
"has the same name as an instance attribute specified in the
"class's declaration part.
DATA inst_string TYPE string.
inst_string = `Local string`.
chg = |The local data object was changed: '{ to_upper( chg ) }'\nChecking the self-reference me:\ninst_string: '{ inst_string }'\nme->inst_string: '{ me->inst_string }'|.
ENDMETHOD.
METHOD inst_meth7.
ret = ipow( base = ip1 exp = ip2 ).
ENDMETHOD.
METHOD inst_meth8.
IF ip1 = 1.
RAISE EXCEPTION TYPE cx_uuid_error.
ELSE.
ret = `No exception was raised.`.
ENDIF.
ENDMETHOD.
METHOD stat_meth1.
"Static methods can only access static attributes.
"DATA(test1) = inst_attr.
DATA(test2) = stat_attr.
"Only read access possible when parameters are passed by value
DATA(a) = ip1.
DATA(b) = ip2.
"Write access is not possible (however, if you need to work with them
"and change the content, you can create copies as above)
"ip1 = `y`.
"ip2 = `z`.
"Pass by value, modification is possible
ip3 = to_upper( ip3 ) && `##`.
"Modifying a read only attribute is possible in the class
"in which it is declared.
read_only_attr = `Read-only attribute was modified`.
ret = |ip1 = '{ ip1 }', ip2 = '{ ip2 }', ip3 (modified) = '{ ip3 }' / read_only_attr = '{ read_only_attr }'|.
ENDMETHOD.
METHOD stat_meth2.
"Using IS SUPPLIED in an IF control structure
IF ip1 IS SUPPLIED.
APPEND |ip1 is supplied, value: '{ ip1 }'| TO ret.
ELSE.
APPEND |ip1 is not supplied, value: '{ ip1 }'| TO ret.
ENDIF.
"Using IS SUPPLIED with the COND operator
APPEND COND #( WHEN ip2 IS SUPPLIED
THEN |ip2 is supplied, value: '{ ip2 }'|
ELSE |ip2 is not supplied, value: '{ ip2 }'| ) TO ret.
ENDMETHOD.
METHOD stat_meth3.
"You may check the content in the debugger.
DATA(a) = REF #( ip_data ).
DATA(b) = REF #( ip_clike ).
DATA(c) = REF #( ip_numeric ).
DATA(d) = REF #( ip_any_table ).
ret = ip_clike.
ENDMETHOD.
ENDCLASS.
```
<p align="right"><a href="#top">⬆️ back to top</a></p>
## Inheritance
- Concept: Deriving a new class (i. e.