Professional Documents
Culture Documents
Horst Keller
SAP AG
SAP AG
SAP AG 2000 F01
TechED Hamburg (Keller) / 1
Workshop Goals
Position of ABAP Objects within the R/3 System Overview of the syntax of ABAP Objects Working with existing classes and interfaces Defining classes and interfaces Creating objects Reacting to events Understanding the polymorphism provided by interfaces and inheritance
Workshop Goals
Contents
Introduction From Function Groups to Classes Classes Objects Events Interfaces Inheritance Using Global Classes Exercises
Introduction
Object Orientation
Data
Data
Data
Attributes Attributes
Data Data
Data
Abstraction Abstraction
Function
Methods Methods
Function Function Function
Function Function
Function
Function
Real-world objects
Information systems have traditionally been defined through their functions. Functions and data were always kept apart, and linked using input/output relationships. At the centre of object-oriented methods are objects. Objects represent abstract or concrete aspects of the real world. Their nature and properties are described by their structure and their attributes (data), and their behavior is described in a set of methods (functions). Objects provide a single shell encompassing both their nature and their behavior. Using objects, you can establish a one-to-one relationship between a real-life problem and its software solution. Typical objects in a business environment are 'customer', 'order', and 'invoice'. The R/3 System has implemented objects of this type since Release 3.1 in the Business Object Repository (BOR). It is intended to integrate the object model of the BOR into ABAP Objects.
Objects
Interface
Private components
Flight
Public attributes
Airline Flight number
Private access
Customer Passengerlist
Address
Public methods
BOOK
Public access
FLIGHT
Public events
The aim of object-oriented modeling is to ensure that each class can ensure its own consistency. This means that data usually belongs to the private section. The internal (private) attributes of the object can only be changed by methods of the same class. The public section usually only contains methods that manipulate the data. Each object has an identifier, which differentiates it from other objects with the same attributes and methods.
ABAP Objects
ABAP Objects is an upwards-compatible extension of the existing ABAP language You can use existing ABAP statements within ABAP Objects You can use ABAP Objects within existing programs ABAP Objects is fully integrated in the ABAP Debugger
Object orientation in ABAP is an extension of the ABAP language that makes available the advantages of object-oriented programming, such as encapsulation, interfaces, and inheritance. This helps to simplify applications and make them more controllable. ABAP Objects is fully compatible with the existing language, so you can use existing statements and modularization units in programs that use ABAP Objects, and can also use ABAP Objects in existing ABAP programs. ABAP Objects has brought stricter syntax in some places that also applies to the existing language. Although the old forms cannot be forbidden (for compatibility reasons) you should use the new forms, even when you are not directly using ABAP Objects. For example, you can no longer refer to a ABAP Dictionary type using LIKE, you must specify types of interface parameters, and the names of components in classes can consist only of the characters "A-Z", "0-9, and "_" and are not allowed to begin with a number.
Function group 1
Function group 2
Function module
Data
Function module
Data
Before Release 4.0, the ABAP components that most closely resembled objects were function groups and their function modules. When a function module is called, an instance of its function group is loaded into the memory area of the internal session. An instance is a real software object. If a single ABAP program calls function modules from more than one function group, it will load more than one instance. The principal difference between 'real' object-orientation and function modules is that a program can work with instances of several function groups simultaneously, but not with several instances of a single function group. For example, a program may need to work with several independent counter variables, or process several orders at once. For this to work, the function group containing the respective function modules would have to be specially programmed to keep the various instances apart.
FUNCTION-POOL COUNTER. FUNCTION-POOL COUNTER. DATA COUNT TYPE I. DATA COUNT TYPE I. FUNCTION SET_COUNTER. FUNCTION SET_COUNTER. * Local Interface IMPORTING VALUE(SET_VALUE) * Local Interface IMPORTING VALUE(SET_VALUE) COUNT = SET_VALUE. COUNT = SET_VALUE. ENDFUNCTION. ENDFUNCTION. FUNCTION INCREMENT_COUNTER. FUNCTION INCREMENT_COUNTER. COUNT = COUNT + 1. COUNT = COUNT + 1. ENDFUNCTION. ENDFUNCTION. FUNCTION GET_COUNTER. FUNCTION GET_COUNTER. * Local Interface: EXPORTING VALUE(GET_VALUE) * Local Interface: EXPORTING VALUE(GET_VALUE) GET_VALUE = COUNT. GET_VALUE = COUNT. ENDFUNCTION. ENDFUNCTION.
The function group COUNTER works as a counter. It contains a global integer field COUNT and three function modules SET_COUNTER, INCREMENT_COUNTER, and GET_COUNTER - that work with the field. Two of the function modules have import and export parameters. These parameters form the data interface of the function group. In terms of object-orientation, a function group has exclusively private attributes, and exclusively public methods.
DATA NUMBER TYPE I VALUE 5. DATA NUMBER TYPE I VALUE 5. CALL FUNCTION 'SET_COUNTER' EXPORTING CALL FUNCTION 'SET_COUNTER' EXPORTING SET_VALUE = NUMBER. SET_VALUE = NUMBER. DO 3 TIMES. DO 3 TIMES. CALL FUNCTION 'INCREMENT_COUNTER'. CALL FUNCTION 'INCREMENT_COUNTER'. ENDDO. ENDDO. CALL FUNCTION 'GET_COUNTER' IMPORTING CALL FUNCTION 'GET_COUNTER' IMPORTING GET_VALUE = NUMBER. GET_VALUE = NUMBER.
A program using the function modules in the group cannot access the COUNT field directly. Instead, operations on the field are fully encapsulated in the function modules. The program can only communicate with the function group by calling the function modules and using their interfaces.
In practice, it is very awkward to manage instances within a function group. Consequently, the data is usually stored in the calling program, and the function modules are called to work with it. This causes a variety of problems. For example, all the programs that use the function modules must use the same data structures as the function group itself. If you change the internal data structure of a function group, you affect a large number of users, and it is often difficult to predict the implications of the changes. Another problem is that all users have copies of the data. When you make changes, it is difficult to ensure consistency (who has a copy of what, and where is it stored?) Working with global data in function groups is too dangerous, since it is almost impossible to predict when a particular function group will be loaded during a complex transaction. These problems are solved by classes. Data and functions are defined in classes instead of function groups. Using classes, an ABAP program can work with any number of runtime instances based on the same template. Instead of loading a single runtime instance of a function group into memory implicitly when a function module is called, the ABAP program can now generate the runtime instances of classes explicitly. The individual runtime instances represent unique objects. You address these using object references.
Example: Class as counter Reference variables Creating objects Calling methods Working with references
CLASS counter DEFINITION. CLASS counter DEFINITION. PUBLIC SECTION. PUBLIC SECTION. METHODS: set IMPORTING METHODS: set IMPORTING VALUE(set_value) TYPE i, VALUE(set_value) TYPE i, increment, increment, get EXPORTING get EXPORTING VALUE(get_value) TYPE i. VALUE(get_value) TYPE i. PRIVATE SECTION. PRIVATE SECTION. DATA count TYPE i. DATA count TYPE i. ENDCLASS. CLASS counter IMPLEMENTATION. ENDCLASS. CLASS counter IMPLEMENTATION. METHOD set. METHOD set. count = set_value. count = set_value. ENDMETHOD. ENDMETHOD. METHOD increment. METHOD increment. count = count + 1. count = count + 1. ENDMETHOD. ENDMETHOD. METHOD get. METHOD get. get_value = count. get_value = count. ENDMETHOD. ENDMETHOD. ENDCLASS. ENDCLASS.
SAP AG 2000 F01
Let us examine the above class COUNTER. The class COUNTER works as a counter. It is an object oriented reflection of the function group COUNTER that we saw in the last section. It contains three public methods - SET, INCREMENT, and GET, all of which work with the private integer field COUNT. You can call the methods from outside the class. Two methods have input and output parameters. These parameters define the data interface of the class. The field COUNT is not visible externally. It represents the encapsulated state of the counter. You will find the details about defining classes in the next chapter.
Reference Variables
DATA: cnt_1 TYPE REF TO counter. DATA: cnt_1 TYPE REF TO counter.
CNT_1
SAP AG 2000 F01
TechED Hamburg (Keller) / 16
In order to create an object of a class you need a reference variable first (here: CNT_1). For declaing reference variables, a new data type REF TO <class> is introduced. Reference variables contain object references. Object references are pointers to objects. In ABAP, they can only be contained in reference variables. Reference variables use reference semantics. When assigning one reference variable to another, with reference semantics, you merely pass the address of the object but not its attributes. In a program, you can only address an object using a reference variable that points to the object. Instance-bound components of an object can only be adressed using a reference variable that points to the object. An object attribute can also be a reference variable.
Creating an Object
DATA: cnt_1 TYPE REF TO counter. DATA: cnt_1 TYPE REF TO counter.
CREATE OBJECT cnt_1 TYPE counter. CREATE OBJECT cnt_1 TYPE counter.
1<COUNTER>
CNT_1
SAP AG 2000 F01
TechED Hamburg (Keller) / 17
An object is an instance of a class. Each object has a unique identifier and its own attributes. All objects exist in the internal session of an ABAP program. A class may have any number of instances (objects). Once you have declared a reference variable with reference to a class, you can create an instance of the class (an object). To do this, use the CREATE OBJECT <cref>. The reference variable <cref> now contains a reference to the object. The names of the instances are shown in the same format as the contents of reference variables in the ABAP Debugger. The value of the number is arbitrary. To distinguish them from classes, instances are displayed with rounded corners. See next chapter for an explanation of the symbols. Each class always contains implicitly the reference variable ME. The reference variable ME contains in objects a reference pointing at the object itself and, therefore, is called self reference. When working in methods with attributes of the own class, you do not need to specify a reference variable. The system uses the self reference ME automatically.
Calling Methods
DATA: cnt_1 TYPE REF TO counter. DATA: cnt_1 TYPE REF TO counter. DATA number TYPE I VALUE 5. DATA number TYPE I VALUE 5. CREATE OBJECT cnt_1 TYPE counter. CREATE OBJECT cnt_1 TYPE counter. CALL METHOD cnt_1->set CALL METHOD cnt_1->set EXPORTING set_value = number. EXPORTING set_value = number. DO 3 TIMES. DO 3 TIMES. CALL METHOD CALL METHOD cnt_1->increment. cnt_1->increment. ENDDO. ENDDO. CALL METHOD cnt_1->get CALL METHOD cnt_1->get IMPORTING get_value = number. IMPORTING get_value = number. 1<COUNTER>
CNT_1
You call a method with CALL METHOD. You must specify the name of the method and an object. The method then works with the attributes of that object. The syntax is: CALL METHOD ref->meth. ref is a reference variable pointing to an object and meth is a method defined in the class of that object. The operator -> is called the object component selector. You can also access methods dynamically using the normal parenthetical semantics (dynamic invocation). Unlike calling subroutines and function modules dynamically, this also allows you to pass parameters and handle exceptions dynamically.
DATA: cnt_1 TYPE REF TO counter, DATA: cnt_1 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_3 TYPE REF TO counter. cnt_3 TYPE REF TO counter.
This creates a series of reference variables with reference to the same class.
Several Objects
DATA: cnt_1 TYPE REF TO counter, DATA: cnt_1 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_3 TYPE REF TO counter. cnt_3 TYPE REF TO counter. CREATE OBJECT: cnt_1, CREATE OBJECT: cnt_1, cnt_2. cnt_2. 2<COUNTER>
1<COUNTER>
You can create any number of instances of the same class in a program. They are fully independent of each other, and have their own identity and attributes with the program. Each CREATE OBJECT statement creates a new object.
DATA: cnt_1 TYPE REF TO counter, DATA: cnt_1 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_3 TYPE REF TO counter. cnt_3 TYPE REF TO counter. CREATE OBJECT: cnt_1, CREATE OBJECT: cnt_1, cnt_2. cnt_2. MOVE cnt_2 TO cnt_3. MOVE cnt_2 TO cnt_3. 2<COUNTER>
1<COUNTER>
You can assign references between reference variables using the MOVE statement. This means that the references in more than one reference variable can point to the same object. When you assign reference variables to each other, their types must be either compatible or convertible. In the cnt_3 = cnt_2 statement, both class references must have the same type, that is, refer to the same class. Alternatively, the class of cnt_3 must be a superclass of the class cnt_2. You can use reference variables with the type OBJECT as containers for passing references, because the class OBJECT is superclass to all classes in ABAP Objects. You cannot use reference variables of type superclass for a static access of addititional components in subclasses. Nevertheless, a dynamic method call (dynamic invoke) is always possible.
DATA: cnt_1 TYPE REF TO counter, DATA: cnt_1 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_3 TYPE REF TO counter. cnt_3 TYPE REF TO counter. CREATE OBJECT: cnt_1, CREATE OBJECT: cnt_1, cnt_2. cnt_2. MOVE cnt_2 TO cnt_3. MOVE cnt_2 TO cnt_3. CLEAR cnt_2. CLEAR cnt_2. 1<COUNTER> 2<COUNTER>
Like other variables, you can initialize a reference variable with the CLEAR statement. The initial value of a reference variable is a reference that does not point to an object.
Garbage Collection
DATA: cnt_1 TYPE REF TO counter, DATA: cnt_1 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_3 TYPE REF TO counter. cnt_3 TYPE REF TO counter. CREATE OBJECT: cnt_1, CREATE OBJECT: cnt_1, cnt_2. cnt_2. MOVE cnt_2 TO cnt_3. MOVE cnt_2 TO cnt_3. CLEAR cnt_2. CLEAR cnt_2. cnt_3 = cnt_1. cnt_3 = cnt_1. 1<COUNTER> 2<COUNTER>
Garbage collection is a mechanism that ensures that memory space that is no longer required is automatically released. The memory space occupied by an object can be released when there are no more references pointing to the object.
Garbage Collection
DATA: cnt_1 TYPE REF TO counter, DATA: cnt_1 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_3 TYPE REF TO counter. cnt_3 TYPE REF TO counter. CREATE OBJECT: cnt_1, CREATE OBJECT: cnt_1, cnt_2. cnt_2. MOVE cnt_2 TO cnt_3. MOVE cnt_2 TO cnt_3. CLEAR cnt_2. CLEAR cnt_2. cnt_3 = cnt_1. cnt_3 = cnt_1. CLEAR cnt_3. CLEAR cnt_3. CNT_3 CNT_2 CNT_1
SAP AG 2000 F01
TechED Hamburg (Keller) / 24
1<COUNTER>
New Objects
DATA: cnt_1 TYPE REF TO counter, DATA: cnt_1 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_3 TYPE REF TO counter. cnt_3 TYPE REF TO counter. CREATE OBJECT: cnt_1, CREATE OBJECT: cnt_1, cnt_2. cnt_2. MOVE cnt_2 TO cnt_3. MOVE cnt_2 TO cnt_3. CLEAR cnt_2. CLEAR cnt_2. cnt_3 = cnt_1. cnt_3 = cnt_1. CLEAR cnt_3. CLEAR cnt_3. CREATE OBJECT: cnt_2, CREATE OBJECT: cnt_2, cnt_3. cnt_3. CNT_3 CNT_2 CNT_1
SAP AG 2000 F01
TechED Hamburg (Keller) / 25
3<COUNTER>
2<COUNTER>
1<COUNTER>
Using the CREATE OBJECT statement, the example creates new objects to which the references in CNT_2 and CNT_3 are pointing. The program would have had the state depicted on the right-hand side, even without the CLEAR CNT_3 statement, since the CREATE OBJECT statement always creates a new object and overwrites the previous contents of the class reference with the new reference.
DATA: cnt_1 TYPE REF TO counter, DATA: cnt_1 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_2 TYPE REF TO counter, cnt_3 TYPE REF TO counter. cnt_3 TYPE REF TO counter. CREATE OBJECT: cnt_1, CREATE OBJECT: cnt_1, cnt_2, cnt_2, cnt_3. cnt_3. CALL METHOD cnt_1->set CALL METHOD cnt_1->set EXPORTING set_value = 1. EXPORTING set_value = 1. CALL METHOD cnt_2->set CALL METHOD cnt_2->set EXPORTING set_value = 10. EXPORTING set_value = 10. CALL METHOD cnt_3->set CALL METHOD cnt_3->set EXPORTING set_value = 100. EXPORTING set_value = 100. CNT_3 CNT_2 1<COUNTER> 2<COUNTER> 3<COUNTER>
CNT_1
The same method is called in different objects. Each object has its own attributes and the method works with the respective attributes for each individual object.
Objects: Summary
Creating objects
CREATE OBJECT: ref1, ref2. CREATE OBJECT: ref1, ref2.
As well as using the CALL METHOD statement, you can also call methods by using them in place of operands in arithmetical or logical expressions. You must use functional methods to do this. A functional method is a method with only one returning parameter (see next chapter). Then, method calls can be written as follows:
No IMPORTING parameters: One IMPORTING parameter: n IMPORTING parameters: meth( ) meth( f1 ) meth( p1 = f1 ) meth( p1 = f1 ... pn = fn )
Classes in Detail
CLASS c1 DEFINITION. PUBLIC SECTION. DATA: a1 METHODS: m1 EVENTS: e1 PROTECTED SECTION. DATA: a2 METHODS: m2 EVENTS: e2 PRIVATE SECTION. DATA: a3 METHODS: m3 EVENTS: e3 ENDCLASS. CLASS c1 IMPLEMENTATION. METHOD m1. ENDMETHOD. METHOD m2. ENDMETHOD. METHOD m3. ENDMETHOD. ENDCLASS.
Class c1 Class c1 Public components a1, m1, e1 Private components a3, m3, e3
Method implementations
Subclasses of c1
Classes are templates for objects. You can either declare them locally in any ABAP program, or globally in the R/3 Repository using the Class Builder in the ABAP Workbench. A class definition consists of a declaration part and an implementation part. The class consists of components. All components are declared in the declaration part of the class. They define the attributes of the class. Each component must be declared in one of the three visibility sections of the class declaration. This defines the external interface of the class. Within a class, all components are visible. The three visibility sections are:
PUBLIC - All components declared in the public section can be addressed within the class and from outside. The public section forms the external interface of the class. PROTECTED - Protected components can be addressed in the methods of the class and its subclasses.
.
PRIVATE - Private components can only be addressed in the methods of the class in which they are declared.
Any methods that you declare in a class must also be implemented in its implementation part. The left-hand side of the diagram shows the declaration and implementation parts of a local class c1. The right-hand side shows the practical consequence of the structure of the class, with the components belonging to various visibility sections, and the method implementations.
CLASS ... DEFINITION. CLASS ... DEFINITION. ... ... ... SECTION. ... SECTION. DATA ... TYPE DATA ... TYPE CLASS-DATA ... TYPE CLASS-DATA ... TYPE CONSTANTS ... TYPE CONSTANTS ... TYPE ... ... ENDCLASS. ENDCLASS.
DATA:
Instance attributes
Attributes are data objects within a class. They can have any ABAP data type. The contents of the attributes of an object determine its state. The contents of the instance attributes (DATA) of a class determine the state of an instance. The contents of the static attributes (CLASS-DATA) of a class determine the state of the class that applies to all instances. There is one set of instance attributes that is shared by the whole class. The READ-ONLY attribute allows you to make the public attributes of a class visble externally, but they may then only be changed within the methods of the class. Constants (declared using CONSTANTS) are special static attributes. You specify their value when you declare them, and this may not subsequently be changed.
CLASS c DEFINITION. CLASS c DEFINITION. PUBLIC SECTION. PUBLIC SECTION. ... ... CLASS-DATA a1(10) TYPE C CLASS-DATA a1(10) TYPE C VALUE 'Static'. VALUE 'Static'. DATA a2(10) TYPE C DATA a2(10) TYPE C VALUE 'Instance'. VALUE 'Instance'. ... ... ENDCLASS. ENDCLASS.
CLASS CLASS a1 a1
...
1<CLASS> a2 ...
WRITE c=>a1. WRITE c=>a1. CREF CREATE OBJECT cref TYPE c. CREATE OBJECT cref TYPE c. WRITE cref->a2. WRITE cref->a2.
Static attributes are independent of instances in the internal session of an ABAP program. They are created when a class is accessed for the first time. You can access static attributes with the class name and the class component selector =>. Instance attributes are created exclusively with the CREATE OBJECT statement and you can access them only with reference variables. You can also access static attributes using object references. However, there value is independent of the object to which the reference is pointing. When methods in different objects but from the same class access a static attribute of that class, they also work with the same data object.
[VALUE] ... [VALUE] ... [VALUE] ... [VALUE] ... [VALUE] ... [VALUE] ... VALUE(...) VALUE(...) ... ...
... [OPTIONAL] ... [OPTIONAL] ... ... ... [OPTIONAL] ... [OPTIONAL] ... ...
METHODS
: Instance methods
Methods are internal procedures within a class. They can access all the attributes in a class, and can therefore change the state of an object. They have a parameter interface. This allows them to receive values from and return values to their caller. Methods may contain declarations of local data types and objects. Local data and interface parameters, that are treated like local variables, obscure those class attributes that have the same names. Instance methods (METHODS) can access all the attributes in a class, and can trigger all of the events in the class. Static methods (CLASS-METHODS) can only access the static attributes of a class, and can only trigger static events. Each method in a class must be implemented in the implementation part of the class definition. The implementation is enclosed between the METHOD and ENDMETHOD statements. The parameter interface must not be named during the method implementation, but only during the method declaration. You call a method using the CALL METHOD statement. This has the same syntax as CALL FUNCTION. Functional methods are methods with any number of IMPORTING parameters and one RETURNING parameter. The RETURNING parameter is always passed by value. Besides calling functional methods with CALL METHOD, you can replace variables with functional methods in expressions. As in function modules, you can use the statements RAISE <exception> and MESSAGE RAISING in methods to handle exceptional situations.
Constructors
CLASS c DEFINITION. CLASS c DEFINITION. PUBLIC SECTION. PUBLIC SECTION. METHODS CONSTRUCTOR METHODS CONSTRUCTOR [IMPORTING arg1 TYPE type ... ]. [IMPORTING arg1 TYPE type ... ]. CLASS-METHODS CLASS_CONSTRUCTOR. CLASS-METHODS CLASS_CONSTRUCTOR. ENDCLASS. ENDCLASS. CLASS c IMPLEMENTATION. CLASS c IMPLEMENTATION. METHOD CONSTRUCTOR. METHOD CONSTRUCTOR. ... ... ENDMETHOD. ENDMETHOD. METHOD CLASS_CONSTRUCTOR. METHOD CLASS_CONSTRUCTOR. ... ... ENDMETHOD. ENDMETHOD. ENDCLASS. ENDCLASS. PROGRAM . PROGRAM . DATA o1 TYPE REF TO c. DATA o1 TYPE REF TO c. CREATE OBJECT o1 EXPORTING arg1 = v1 ... CREATE OBJECT o1 EXPORTING arg1 = v1 ...
SAP AG 2000 F01
TechED Hamburg (Keller) / 33
The constructors CONSTRUCTOR and CLASS_CONSTRUCTOR are special methods that are called implicitly when you create an object (CONSTRUCTOR) or when you first access a class (CLASS_CONSTRUCTOR). Constructors cannot be called using CALL METHOD. Instead, they are automatically called by the system to define the initial state of an object or class A class can have an instance constructor, which is called automatically in the CREATE OBJECT statement after the object has been created, and a static constructor, which is automatically called before the first access to the class. These methods have the reserved names CONSTRUCTOR and CLASS_CONSTRUCTOR respectively. An instance constructor can only have IMPORTING parameters. Static constructors have no parameters. You must fill the IMPORTING parameters of the instance constructor in the CREATE OBJECT statement. Constructors are necessary whenever you need to set the initial state of an object dynamically, and the VALUE addition of the DATA statement is insufficient. The constructors are always present, even if you do not declare them explicitly. The explicit declaration is only necessary when you want to implement a constructor for a class.
Instance components
ref>comp ref->attr call method ref->meth class=>comp class=>attr call method class=>meth
n<class> ...
ME
ME->comp SUPER->comp
To access a component from the inside, meaning in a method of the same class, you need only the components name. The self reference ME is used implicitly. To access a component from the outside, for instance components you must name the object with the object component selector -> and for static components the class with the class component selector =>.. When accessing components from the inside, special references are possible:
Explicit use of the self reference: Call of the superclass method during method redefinition: ME->attr CALL METHOD ME->meth CALL METHOD SUPER->meth
You can access methods dynamically using the normal parenthetical semantics (dynamic invocation) : CALL METHOD ref->(name) PARAMETER-TABLE ptab EXCEPTION-TABLE etab. Unlike calling subroutines and function modules dynamically, this also allows you to pass parameters and handle exceptions dynamically.
Inheritance
Introduction Overview Single inheritance Redefining methods Example: Subclass of superclass counter
Inheritance: Introduction
Definition of a class by inheriting the components from a superclass (Reuse) Specialization by adding own components and redefining methods in subclasses Polymorphism by accessing subclass objects
n<class3> class1 CREF1
class2 CREF2
class3 CREF3
SAP AG 2000 F01
TechED Hamburg (Keller) / 36
Inheritance allows you to derive subclasses from superclasses. Subclasses contain the attributes, methods and events of all their superclasses. You can add new components in each subclass or re-implement existing methods. Reference variables, that have the type of a superclass can point to subclass objects. Above, three reference variables of different type point to an object of class CLASS3 which is a subclass of superclasses CLASS2 and CLASS1.
Inheritance - Overview
Class OBJECT
...
CLASS c1 DEFINITION INHERITING FROM ... ... ENDCLASS. CLASS c1 IMPLEMENTATION. ... ENDCLASS. Class c2 CLASS c2 DEFINITION INHERITING FROM c1. ... ENDCLASS. CLASS c2 IMPLEMENTATION. ... ENDCLASS. Class ... ...
SAP AG 2000 F01
TechED Hamburg (Keller) / 37
Class c1
Inheritance allows you to derive new classes from existing ones. The new class adopts (inherits) all components of the existing class. The new class is known as the subclass, the existing class as the superclass. The coding of superclasses is reused in subclasses. Only the components of the public and protected sections of the superclass are visible in its subclasses. You can define extra components in the subclass, making it more specialized than the superclass. A subclass of a class can also become a superclass of a further new class. This allows you to introduce several degrees of specialization. Like all components, static attributes exist only once in each branch of an inheritance tree. A subclass can access the content of the public and protected static attributes of all superclasses. Conversely, a superclass shares its public and protected static attributes with all subclasses. Thus static attributes are not assigned to one single class but to a branch of the inheritance tree. They are visible and modifiable in all classes involved. Changes can be made from outside using the class component selector => with all class names involved or from inside in all associated classes.
Single Inheritance
OBJECT
C1
...
...
C2
...
TechED Hamburg (Keller) / 38
Classes can have several direct subclasses, but only a single superclass. ABAP Objects thus only supports single inheritance. When a subclass inherits from a superclass that is itself a subclass of another class, the classes involved form an inheritance tree, which becomes more specialized as we move from top to bottom. Conversely, superclasses can be seen as generalizations of subclasses. The root node of all ABAP Objects inheritance trees is the predefined class OBJECT. This is an implicit class - you do not have to specify it as the superclass of every new class in ABAP Objects. In the inheritance tree, all nodes higher than the current one are superclasses. All those below the current level are subclasses. The declaration of subclass components is distributed over all superclasses of the respective branch of the inheritance tree. It is always possible to assign the contents of a reference variable defined with reference to a subclass to a reference variable defined with reference to one of its superclasses or interfaces. Above all, you can always specify the class OBJECT for the target variable. Statically, users can only address the known components of a class. Redefining methods within subclasses is one of the bases for polymorphism. Dynamic method calls allow users to address specializations within subclasses.
Redefining Methods
CLASS ... DEFINITION INHERITING FROM ... CLASS ... DEFINITION INHERITING FROM ... ... SECTION. ... SECTION. METHODS ... REDEFINITON ... METHODS ... REDEFINITON ... ... ... ... ... ENDCLASS. ENDCLASS.
CLASS ... IMPLEMENTATION. CLASS ... IMPLEMENTATION. METHOD ... METHOD ... ... ... ENDMETHOD. ENDMETHOD. ENDCLASS. ENDCLASS.
Semantic rules Subclasses must behave just like their superclass for all users of inherited components A redefined method must observe the original semantics Inheritance should only be used to specialize
SAP AG 2000 F01
TechED Hamburg (Keller) / 39
Each subclass contains the components of all classes that appear in the inheritance tree between it and the root node. The visibility of a component always remains the same and cannot be changed. You can specialize the public and protected instance methods of all preceding superclasses by redefining them using the REDEFINITION addition of the METHODS statement. You cannot change the interface of a redefined method. Redefined methods are merely implemented differently under the same name. Within a redefined method, you can use the pseudoreference SUPER to access the method with the same name in the superclass, for example, to adopt and extend its functions. The additions ABSTRACT and FINAL of the METHODS and CLASS statements allow you to define abstract and final methods and classes. Abstract methods are defined in abstract classes, and cannot be implemented in the same class. Instead, they have to be implemented in a subclass. You cannot instantiate an abstract class. You cannot redefine a final method in a subclass. Final classes cannot have any further subclasses, and therefore conclude an inheritance tree.
CLASS subclass DEFINITION INHERITING FROM superclass. CLASS subclass DEFINITION INHERITING FROM superclass. PUBLIC SECTION. PUBLIC SECTION. METHODS CONSTRUCTOR IMPORTING ... METHODS CONSTRUCTOR IMPORTING ... ... ... ENDCLASS. ENDCLASS. CLASS subclass IMPLEMENTATION. CLASS subclass IMPLEMENTATION. METHOD CONSTRUCTOR. METHOD CONSTRUCTOR. Access to static ... ... attributes only CALL METHOD SUPER->CONSTRUCTOR EXPORTING ... CALL METHOD SUPER->CONSTRUCTOR EXPORTING ... ... ... ENDMETHOD. ENDMETHOD. Accress to instance ... ... attributes also ENDCLASS. ENDCLASS. PROGRAM ... PROGRAM ... DATA o1 TYPE REF TO subclass. DATA o1 TYPE REF TO subclass. CREATE OBJECT o1 TYPE subclass EXPORTING ... CREATE OBJECT o1 TYPE subclass EXPORTING ...
SAP AG 2000 F01
TechED Hamburg (Keller) / 40
There are special rules for constructors in inheritance. You cannot redefine the instance constructor of a superclass in its subclasses. An instance constructor of a subclass must contain the method call CALL METHOD SUPER>CONSTRUCTOR, which calls the instance constructor of its direct superclass. The only exception to this rule are the subclasses of the root node of the inheritance tree OBJECT. In subclasses that do not have an explicitly-defined instance constructor, an implicit constructor (which always exists) is executed that automatically calls the instance constructor of the immediate superclass. When you call an instance constructor with CREATE OBJECT or CALL SUPER->CONSTRUCTOR , you must assign values to all non-optional interface parameters of the next-highest explicit instance constructor in the hierarchy . The instance constructor of a subclass is divided into two parts by the required CALL METHOD SUPER->CONSTRUCTOR. In the statements before the SUPER->CONSTRUCTOR call, the constructor behaves like a static method, that is, it cannot access the instance attributes of its class. After the call, however, it can also address the instance attributes. The first time you address a subclass in a program, the static constructor is called. Before this, however, all static constructors further up the entire inheritance tree must also have been executed. Bearing in mind that a static constructor can only be called once during the runtime of a program, the system searches for the next-highest superclass in the inheritance hierarchy whose static constructor has not yet been called. It then calls this static constructor and those of all of its subclasses down to the subclass that you addressed.
The class CL_COUNTER_TEN is derived from class COUNTER. It redefines the method INCREMENT. To achieve this, the COUNT attribute must be moved from the private section of COUNTER to the protected section. The subclass influences the superclass!. The redefined method calls the obscured method of the superclass using the pseudoreference SUPER->. The redefinition of the method specializes the inherited method. An object of (dynamic) type subclass is created and a reference variable of (static) type superclass is pointing to it. When you call method INCREMENT via a superclass reference in a subclass object, the redefined method of the subclass is executed. That is what polymorphism means. You acces an object with a reference variable of one type but the object itself has another type.
Interfaces
Introduction Overview Definition Implementation Interface references Example: Interface for counter
Interfaces: Introduction
Definition of an interface without implementation Classes can implement several interfaces Uniform access with interface references Polymorphism independent from inheritance
n<class3>
iref_tab
Interface
Interfaces are defined independently of classes. They contain declarations for attributes, methods and events. Classes can implement interfaces. Such classes expose an uniform point of contact to the public and are obliged to provide the functions of the interfaces by implementing their methods. You can type reference variables referring to interfaces, but there are no instances of interfaces. Interface references can point to objects of different classes. Above, an internal table has the line type of an interface reference variable and contains references to objects of different classes, all of them implementing the respective interface.
Interfaces - Overview
Class c1 Class c1 Public components a1,... i1~a1, i1~m1, ... Private components a2, m2, e2
Method implementations
CLASS c1 DEFINITION. PUBLIC SECTION. DATA a1 ... INTERFACES i1 ... PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS c1 IMPLEMENTATION. METHOD i1~m1. ENDMETHOD. ENDCLASS.
SAP AG 2000 F01
TechED Hamburg (Keller) / 44
Subclasses of c1
The public components of a class define the external point of contact for the class. Interfaces are independent structures that allow you to extend this public point of contact or define it fully for a particular class. They allow you to address different classes in a uniform way. The left-hand side of the diagram shows the definition of a local interface i1 and the declaration and implementation parts of a local class c1, which implements the interface i1 in its public section. The interface method i1~m1 must be implemented in the implementation part of the class. The right-hand side shows the structure of the class, composed of the components of each visibility section and the method implementations. The interface components extend the external face of the class. All users can access both the class-specific public components and the components of the interface. Interfaces, along with inheritance, provide the basis for the polymorphism of classes, since a method of an interface can be implemented in different ways in different classes. One class can implement several parallel interfaces.
Interfaces - Definition
INTERFACE ... INTERFACE ... ... ... DATA: DATA: CLASS-DATA: CLASS-DATA: CONSTANTS: CONSTANTS:
. . ... ... ... ... ... ... TYPE TYPE TYPE TYPE TYPE TYPE ... ... ... ... ... ... [READ-ONLY] ... [READ-ONLY] ... [READ-ONLY] ... [READ-ONLY] ... [VALUE ...] [VALUE ...] TYPE TYPE TYPE TYPE TYPE TYPE TYPE TYPE ... [OPTIONAL] ... [OPTIONAL] ... ... ... [OPTIONAL] ... [OPTIONAL] ... ...
METHODS: ... IMPORTING METHODS: ... IMPORTING EXPORTING EXPORTING CHANGING CHANGING RETURNING RETURNING EXCEPTIONS EXCEPTIONS CLASS-METHODS: ... CLASS-METHODS: ...
[VALUE] ... [VALUE] ... [VALUE] ... [VALUE] ... [VALUE] ... [VALUE] ... VALUE(...) VALUE(...) ... ...
EVENTS: ... [EXPORTING VALUE(...) TYPE ... [OPTIONAL]]. EVENTS: ... [EXPORTING VALUE(...) TYPE ... [OPTIONAL]]. CLASS-EVENTS:... CLASS-EVENTS:... INTERFACES: ... INTERFACES: ... ENDINTERFACE. ENDINTERFACE.
Like classes, you can define interfaces either globally in the R/3 Repository, or locally within an ABAP program. They can contain the same components as classes (attributes, methods, events, and constants). However, the methods are not implemented in the interface itself, but rather in the classes that implement it. You do not have to assign the components of interfaces to a visibility area. Instead, all components automatically belong to the public section of the class implementing the interface. Interfaces allow you to define components that are common to several classes at one central point. When a class implements an interface, it must also implement all of its methods. The methods of an interface are abstract, since they can be implemented differently in each class. You can nest interfaces using the INTERFACES statement between the INTERFACE and ENDINTERFACE statements. For implementation, the components of a nested interface all belong to the same level, so a nested interface only contains one instance of each interface component, even if a component interface is itself a component of another component interface. You can define ALIASES for components of compound interfaces.
Interfaces - Implementation
CLASS ... DEFINITION. CLASS ... DEFINITION. PUBLIC SECTION. PUBLIC SECTION. INTERFACES: ... INTERFACES: ... ... ... ... ... ENDCLASS. ENDCLASS.
CLASS ... IMPLEMENTATION. CLASS ... IMPLEMENTATION. METHOD ...~... METHOD ...~... ... ... ENDMETHOD. ENDMETHOD. ENDCLASS. ENDCLASS.
Unlike classes, interfaces do not have instances. Instead, they are implemented by classes in the public visibility section. When you implement an interface in a class, the components of the interface are added to the components of the public section of the class. To address a component comp of an interface intf, use the name intf~comp. The components of implemented interfaces are fully equivalent to normal components of the class. The class must implement all methods of the interface itself in its implementation part: METHOD intf~imeth - ENDMETHOD. An interface can be implemented by several classes, each of which is extended by the same set of components. The methods of the interface can be implemented differently in each implementing class. You can define ALIASES for the components of implemented interfaces.
Interface References
INTERFACE i1. INTERFACE i1. ... ... ENDINTERFACE. ENDINTERFACE. CLASS c1 DEFINITION. CLASS c1 DEFINITION. PUBLIC SECTION. PUBLIC SECTION. DATA a1. DATA a1. INTERFACES i1. INTERFACES i1. ENDCLASS. ENDCLASS. CLASS c2 DEFINITION. CLASS c2 DEFINITION. PUBLIC SECTION. PUBLIC SECTION. INTERFACES i1. INTERFACES i1. ENDCLASS. ENDCLASS. CNT_1 DATA cnt_c TYPE REF TO c1. DATA cnt_c TYPE REF TO c1. DATA: cnt_1 TYPE REF TO i1, DATA: cnt_1 TYPE REF TO i1, cnt_2 LIKE cnt_1. cnt_2 LIKE cnt_1. CREATE OBJECT: cnt_c TYPE c1, CREATE OBJECT: cnt_c TYPE c1, cnt_1 TYPE c2. cnt_1 TYPE c2. CNT_2 MOVE cnt_c to cnt_2. MOVE cnt_c to cnt_2.
SAP AG 2000 F01
TechED Hamburg (Keller) / 47
1<C2>
1<C1>
CNT_C
You use reference variables to access objects. As well as reference variables that refer to a class, you can also create then with reference to an interface. These reference variables can contain references to objects of classes that implement the relevant interface. The interface <iref> allows the user to access all of the interface components <icomp> of the object to which the reference points. This means that the user can access the components that were added to the class definition by the interface implementation. When you use interface reference variables, the (static) type of the reference variable and the (dynamic) type of the object it is pointing to are always different (polymorphism).
CLASS bicycle DEFINITION. CLASS bicycle DEFINITION. PUBLIC SECTION. PUBLIC SECTION. INTERFACES status. INTERFACES status. METHODS drive. METHODS drive. PRIVATE SECTION. PRIVATE SECTION. DATA speed TYPE i. DATA speed TYPE i. ENDCLASS. ENDCLASS.
The interface STATUS writes the state of an object (its attributes) to a list. It contains the method WRITE to do so. Two classes implement the interface and its method.
TYPE REF TO counter, TYPE REF TO counter, TYPE REF TO bicycle, TYPE REF TO bicycle, TYPE REF TO status. TYPE REF TO status.
CREATE OBJECT: count, bike. CREATE OBJECT: count, bike. DO 5 TIMES. DO 5 TIMES. CALL METHOD: count->increment, CALL METHOD: count->increment, bike->drive. bike->drive. ENDDO. ENDDO. status = count. status = count. CALL METHOD status->write. CALL METHOD status->write. status = bike. status = bike. CALL METHOD status->write. CALL METHOD status->write.
Counter status
Bike speed
Events
Introduction Overview Declaring and triggering events Event handler methods Handling events Example: Overflow in counter
Events - Introduction
Events are components of classes Methods can raise the events of their class Handler methods can be triggered by events
Objects can announce externally that their state has changed by triggering an event. Other objects can contain handler methods that are executed when the event is triggered. In contrast to normal method calls, where the caller has the control and knows the called method, an event trigger never knows who will handle the event. This is the principle of publish and subscribe, which holds statically for the definition of the event and its handlers as well as dynamically for raising and handling the event. A class can declare events statically during its definition and an object can raise events during runtime without having to know whether or by whom they are used. Examples, for where events are frequently used are user interactions on screens or changes of state during workflow.
Events - Overview
CLASS c1 DEFINITION. PUBLIC SECTION. EVENTS e1 EXPORTING VALUE(p1) TYPE i. METHODS m1. PRIVATE SECTION. DATA a1 TYPE i. ENDCLASS. CLASS c1 IMPLEMENTATION. METHOD m1. a1 = ... RAISE EVENT e1 EXPORTING p1 = a1. ENDMETHOD. ENDCLASS.
CLASS c2 DEFINITION. PUBLIC SECTION. METHODS m2 FOR EVENT e1 OF c1 IMPORTING p1. PRIVATE SECTION. DATA a2 TYPE i. ENDCLASS.
Event trigger
SAP AG 2000 F01
TechED Hamburg (Keller) / 52
Event handler
To be able to trigger an event, a class must declare the event in its declaration part and raise it in one of its methods.. Events can contain EXPORTING parameters, but since their purpose is only to announce that the object has changed its state, they cannot have IMPORTING parameters.. Events are handled by special methods. To handle an event, a method must have been declared as a handler method for that event, and must have been registered for it at runtime. In the above example, class C1 has an event E1, which is triggered by the method M1. Class C2 contains a method M2 that can handle event E1 from class C1.
You declare events in the declaration part of a class. There are two kinds instance events and static events. Events can have EXPORTING parameters. These are always passed by value, and reflect the state of the triggering object. If a class contains an instance event, it may be triggered by any instance method of the class. Static events can be triggered by any method of the class. Static methods may only trigger static events. You can trigger an event in a method using the RAISE EVENT statement. You must use the EXPORTING addition of the RAISE EVENT to pass all of the event parameters that are non-optional.
CLASS ... DEFINITION. CLASS ... DEFINITION. ... SECTION. ... SECTION. METHODS ... FOR EVENT ... OF ... [IMPORTING ... SENDER ... ]. METHODS ... FOR EVENT ... OF ... [IMPORTING ... SENDER ... ].
ENDCLASS. ENDCLASS.
CLASS ... IMPLEMENTATION. CLASS ... IMPLEMENTATION. METHOD ... METHOD ... ... ... ENDMETHOD. ENDMETHOD. ENDCLASS. ENDCLASS.
Any class may contain event handler methods for events of other classes. The interface of an event handler method may only contain formal parameters that have been defined in the declaration of the corresponding event. The attributes of the parameters are also inherited from the event definition. However, the event handler method does not have to accept and use all of the parameters passed in the RAISE EVENT statement. Events have an implicit parameter called SENDER, which you can accept as a normal IMPORTING parameter. This allows the event handler for an instance event to access the triggering instance. If you declare an event handler method in a class, the instances of the class or the class itself is then capable of handling the event.
PROGRAM ... PROGRAM ... DATA: trigger DATA: trigger handler_1 handler_1 handler_2 handler_2 TYPE TYPE TYPE TYPE TYPE TYPE REF REF REF REF REF REF TO TO TO TO TO TO trigger, trigger, handler, handler, handler. handler.
CREATE OBJECT: trigger, handler_1, handler_2. CREATE OBJECT: trigger, handler_1, handler_2. SET HANDLER handler_1->handle_event SET HANDLER handler_1->handle_event handler_2->handle_event FOR trigger. handler_2->handle_event FOR trigger. CALL METHOD trigger->raise_event. CALL METHOD trigger->raise_event.
If you want an event handler method to react to an event, you must define at runtime the trigger to which you want it to respond. The SET HANDLER statement links a list of handler methods to corresponding event triggers - either instance events or static events. The syntax and effect of the SET HANDLER statement differs according to the event type. With instance events, you must use the FOR addition to specify the triggering instance for which you want to register the trigger. You can either specify a single triggering instance using a reference variable <ref>, or specify the handler for all instances using the statement SET HANDLER FOR ALL INSTANCES. FOR ALL INSTANCES also applies to triggering instances that do not yet exist when the registration is made. You cannot use the FOR addition with static events. Instead, the registrtation applies automatically to the entire class or all classes that implement an interface with a static event. The SET HANDLER statement also has an addition ACTIVATION, which allows you to register and deregister handlers automatically.
2<HANDLER>
1<HANDLER>
.
1<TRIGGER>
Unlike methods, where the caller has control of the program, and knows the called method, the trigger of an event does not know which methods, if any, are registered for it. For each SET HANDLER statement, the system creates an entry in a handler table, invisible to the user, for each triggering instance of each event for which a handler method has been registered. The handler table contains the names of the handler methods and references to the registered handling instances. Entries in the table are created by the SET HANDLER statement. A reference to an instance in a handler table counts as a use of the instance, exactly like a reference in a reference variable. Handler table entries therefore affect the lifetime of objects. In the above illustration, this means that the instances 1<HANDLER> and 2<HANDLER> are not deleted by the garbage collector as long as they are registered for event handling, even if the reference varaibles HANDLER_1 and HANDLER_2 are initialized. You can delete entries from the handler table using the ACTIVATION addition of the SET HANDLER statement. If the triggering instance is deleted by the garbage collector, the entire handler table, including all its references, is deleted. Static events have a handler table for the class that is not instance-specific. When an event is triggered, the system searches the corresponding event table and executes the listed methods in their instances (or classes, in the case of static handler events).
The class COUNTER implements a counter. It triggers the event CRITICAL_VALUE when a threshold is exceeded, and passes the difference as a parameter.
The class HANDLER handles the exception in COUNTER. The handler is registered at runtime using a reference variable that points to the object.
Class pools Class Browser and Class Builder Class Builder Example: Using CL_GUI_PICTURE
Class Pools
CLASS-POOL ... TYPES TYPES CLASS CLASS ... ... ENDCLASS. ENDCLASS. INTERFACE INTERFACE ... ... ENDINTERFACE. ENDINTERFACE.
Visibility
CLASS DEFINITION PUBLIC. CLASS DEFINITION PUBLIC. ... ... ENDCLASS. ENDCLASS.
Globally-defined classes and interfaces are contained within special ABAP programs called class pools (type K) or interface pools (type J) respectively. Each class or interface pool contains the definition of a single global class or interface. The programs are automatically generated when you create a class or interface using the Class Builder. A class pool is similar to a module pool or function group. It contains declarative and executable ABAP statements, but cannot be started on its own. The runtime system can create instances of the class (objects) when requested to do so by the CREATE OBJECT statement. These instances can execute the statements in the class pool. Class pools contain a definition part for declarative statements, a declaration part and implementation part for the class, and implementation parts for local classes. The local classes and interfaces that you define in the definition part of a class pool are not externally visible. They have a similar function to local classes and interfaces in other ABAP programs. Local classes can only be instantiated in methods of the global class. Since class pools may not contain subroutines, local classes are the only way of modularizing the functions of a global class.
Global transportable classes are administered in the class library. The class library also allows you to work with local definitions. The Class Browser provides a hierarchical view of the class library. You can start the Class Browser from the Class Builder. Unlike function modules and function groups, the rollout of global transportable classes is controlled. Internal quality assurance for the class library at SAP will probably become the task of the BAPI/BOR group when the BOR is incorporated in the class library.
Class Builder
You create global classes and interfaces using the Class Builder. You define the components of the class or interface on the screen. The Class Builder then generates the corresponding declarative coding automatically. You only have to use the ABAP Editor to implement the methods. The above illustration is an extract from the methods of the global class CL_GUI_PICTURE. Here you see only the specializations of the subclass, but you can also choose to display the methods that are inherited from superclasses.
Above are extracts from program DEMO_ABAP_OBJECTS_SPLIT_SCREEN that uses global classe from the CFW (Control Framework). There is a local class SCREEN_HANDLER to handle events from CL_GUI_SIMPLE_TREE. There are reference variables that can point to objects of CL_GUI_PICTURE, CL_GUI_SIMPLE_TREE, CL_GUI_HTML_VIEWER ... For further information about GUI controls, refer to the SAP Control Framework documentation.
The illustration shows how you can use the classes of the CFW to place various controls on a screen.
Mouse Click
CL_GUI_HTML_VIEWER
Further Information
Further Information
Keyword Documentation
Further Information
Example Library
Exercises
1. Defining classes 2. Creating objects 3. Deriving classes using inheritance 4. Using interfaces 5. Triggering and handling events
Exercises - Scenario
Interface Status With methods for displaying attributes
Class "Vehicle" with attribute for speed, and a method for changing it
Class "Helicopter" Can handle events from ship Class "Truck" with its own maximum speed and attribute output
SAP AG 2000 F01
Class "Ship" with its own maximum speed and attribute output, a name, and an event
During the exercises, you will write a program in five steps to realize the above scenario.
Exercise 1 - Classes
Copy the template ABAP_OBJECTS_ENJOY_0 into an own program. Define a local class VEHICLE in the designated area in front of the predefined class MAIN. Class VEHICLE should have the protected instance attributes SPEED and MAX_SPEED for its speed and maximum speed, and the public methods SPEED_UP, STOP, and WRITE. SPEED_UP should have an IMPORTING parameter STEP. The method should increase the speed by STEP, but not allow it to exceed the maximum speed. STOP should reset the speed to zero. WRITE should display a list line containing the speed and the maximum speed.
method START. During program execution, START is called during the system event START-OF-SELECTION. You do not need MAIN during exercise 1 yet.
VEHICLE: Class for vehicles SPEED: Speed. Type integer, starting value 0. MAX_SPEED: Maximum speed. Type integer, starting value 50. SPEED_UP: Increases SPEED by STEP (type I). If SPEED > MAX_SPEED, set
SPEED to MAX_SPEED.
STOP: Set SPEED to zero. WRITE: Display the following line: Vehicle speed = SPEED Max. speed =
MAX_SPEED.
Exercise 2 - Objects
Continuing the program from exercise 1, create objects from the class VEHICLE. Program the respective coding in the predefined method START of class MAIN. Define a reference variable VEHICLE with type VEHICLE, and an internal table VEHICLE_TAB, whose line type is also a reference variable to this class. In a DO loop, create a number of instances of the class VEHICLE and insert them into the internal table. In a LOOP construction, call the methods SPEED_UP and WRITE once for each entry in the internal table. When you call SPEED_UP, pass the value SY-TABIX * 10 to the parameter STEP.
START: method of class MAIN, that will contain all data declarations and
statements to create objects and to work with the objects. Encapsulating the functions of the program in method START circumvents the declaration of unnecessary global data.
VEHICLE: Reference variable defined with reference to class VEHICLE. VEHICLE_TAB: Internal table with line type defined with reference to class
VEHICLE.
DO loop: Series of CREATE OBJECT with VEHICLE, appended to
VEHICLE_TAB..
LOOP: Read from VEHICLE_TAB to VEHICLE and call the methods SPEED_UP
and WRITE.
TABINDEX: Auxiliary variable with type I for calculating the actual parameter for
Exercise 3 - Inheritance
Change your program from exercise 2 to define classes TRUCK and SHIP as direct subclasses of VEHICLE. The class TRUCK should have an instance constructor and redefine the method WRITE. The class SHIP should have an IMPORTING parameter NAME, a new public attribute NAME, and should also redefine the method WRITE. The instance constructor of each class should change the maximum speed. The instance constructor of SHIP should set the attribute NAME to the actual parameter that you imported. The WRITE method should show the class from which the display comes. For SHIP, use the NAME attribute. Declare extra reference variables TRUCK and SHIP for the new classes. You can delete the code that creates objects for VEHICLE. Instead, create one instance of each of your new classes and place the corresponding reference into VEHICLE_TAB. Call the method SPEED_UP for both classes using the correct subclass reference, and WRITE using a superclass reference.
SAP AG 2000 F01
TRUCK: Reference variable with reference to class TRUCK SHIP: Reference variable with reference to class SHIP. When you create a ship using CREATE OBJECT, pass a name for the ship. The speeds of the truck and ship should be increased by 30 and 10 respectively. Use VEHICLE_TAB for the output, as before.
Exercise 4 - Interfaces
Change your program from exercise 3 so that the method WRITE is contained in an interface STATUS. The class VEHICLE should implement the interface instead of its own WRITE method. The name must be changed accordingly in each implementation (including the subclasses), but the function remains the same. Replace the reference variables VEHICLE and the table VEHICLE_TAB with the interface reference STATUS and internal table STATUS_TAB. Use these references to display the status of the objects. Create a new class HELICOPTER that also implements STATUS. Declare an alias WRITE in that class for the interface method. The interface method in HELICOPTER should display a different line from that displayed in VEHICLE. Declare a reference variable HELI for the class HELICOPTER, create a corresponding object, and insert the reference variable into the table STATUS_TAB.
SAP AG 2000 F01
TechED Hamburg (Keller) / 75
STATUS: Interface with method WRITE. VEHICLE: Implements STATUS and its method STATUS~WRITE. TRUCK, SHIP: Redefine STATUS~WRITE. HELICOPTER: Implements STATUS and its method STATUS~WRITE. HELICOPTER: ALIASES WRITE FOR STATUS~WRITE. STATUS~WRITE in HELICOPTER: Display the following: 'Helicopter' .
STATUS: Reference variable with reference to STATUS. STATUS_TAB: Internal table with line type reference to STATUS.
Exercise 5 - Events
Change your program from exercise 4 to include an event DAMAGED for the class SHIP. Redefine the method SPEED_UP in the class SHIP. When the maximum speed is exceeded, SPEED_UP should set the maximum speed to zero and trigger the event DAMAGED. Add a new method RECEIVE to the class HELICOPTER to allow it to handle the event DAMAGED. Import the implicit parameter SENDER. RECEIVE should use the SENDER parameter to display the name of the ship that triggered the event. Register the handler method of the object to which HELI is pointing as a handler for objects from the class SHIP. Increase the speed of the object from the class SHIP until it exceeds the maximum speed and triggers the event.
SHIP: Declare the event DAMAGED and redefine SPEED_UP. SPEED_UP in SHIP: If SPEED > MAX_SPEED, set MAX_SPEED to zero, call the method STOP, and trigger the event DAMAGED. HELICOPTER: New method RECEIVE as handler for DAMAGED from CL_SHIP with IMPORTING parameter SENDER. RECEIVE: Call the alias method WRITE and additionally display the following: 'received call from' SENDER->NAME. Register HELI->RECEIVE for all instances of class SHIP using SET HANDLER. In a DO loop, increase the speed of the ship in increments of 10 until the maximum speed is exceeded.