Uploaded by tendo06

BC401 EN Col16 ABAP Objects

advertisement
BC401
ABAP Objects
.
.
PARTICIPANT HANDBOOK
INSTRUCTOR-LED TRAINING
.
Course Version: 16
Course Duration: 5 Day(s)
e-book Duration: 36 Hours 40 Minutes
Material Number: 50134934
SAP Copyrights and Trademarks
© 2016 SAP SE or an SAP affiliate company. All rights reserved.
No part of this publication may be reproduced or transmitted in any form or for any purpose
without the express permission of SAP SE or an SAP affiliate company.
SAP and other SAP products and services mentioned herein as well as their respective
logos are trademarks or registered trademarks of SAP SE (or an SAP affiliate company) in
Germany and other countries. Please see http://global12.sap.com/corporate-en/legal/
copyright/index.epx for additional trademark information and notices.
Some software products marketed by SAP SE and its distributors contain proprietary
software components of other software vendors.
National product specifications may vary.
These materials are provided by SAP SE or an SAP affiliate company for informational
purposes only, without representation or warranty of any kind, and SAP SE or its affiliated
companies shall not be liable for errors or omissions with respect to the materials. The only
warranties for SAP SE or SAP affiliate company products and services are those that are
set forth in the express warranty statements accompanying such products and services, if
any. Nothing herein should be construed as constituting an additional warranty.
In particular, SAP SE or its affiliated companies have no obligation to pursue any course of
business outlined in this document or any related presentation, or to develop or release any
functionality mentioned therein. This document, or any related presentation, and SAP SE’s
or its affiliated companies’ strategy and possible future developments, products, and/or
platform directions and functionality are all subject to change and may be changed by SAP
SE or its affiliated companies at any time for any reason without notice. The information in
this document is not a commitment, promise, or legal obligation to deliver any material,
code, or functionality. All forward-looking statements are subject to various risks and
uncertainties that could cause actual results to differ materially from expectations. Readers
are cautioned not to place undue reliance on these forward-looking statements, which
speak only as of their dates, and they should not be relied upon in making purchasing
decisions.
Typographic Conventions
American English is the standard used in this handbook.
The following typographic conventions are also used.
This information is displayed in the instructor’s presentation
Demonstration
Procedure
Warning or Caution
Hint
Related or Additional Information
Facilitated Discussion
User interface control
Example text
Window title
Example text
© Copyright. All rights reserved.
iii
iv
© Copyright. All rights reserved.
Contents
ix
Course Overview
1
Unit 1:
2
14
Lesson: Explaining the Object-Oriented Programming Model
Lesson: Analyzing and Designing with Unified Modeling Language
(UML)
Exercise 1: Create UML Diagrams
27
37
Unit 2:
39
53
60
67
71
77
83
87
95
99
115
Fundamental Object-Oriented Syntax
Lesson: Creating Local Classes
Exercise 2: Create Local Classes
Lesson: Creating Objects
Exercise 3: Create Objects
Lesson: Accessing Methods and Attributes
Exercise 4: Call Methods
Lesson: Implementing Constructors in Local Classes
Exercise 5: Create and Use Constructors
Lesson: Implementing Class Constructors in Local Classes
Exercise 6: Create and Use Static Constructors
Unit 3:
116
125
135
139
144
149
155
159
173
Introduction to Object-Oriented Programming
Inheritance and Casting
Lesson: Implementing Inheritance
Exercise 7: Implement Inheritance
Lesson: Implementing Upcasts Using Inheritance
Exercise 8: Implement Upcasts
Lesson: Implementing Polymorphism Using Inheritance
Exercise 9: Implement Polymorphism Using Inheritance
Lesson: Implementing Downcasts Using Inheritance
Exercise 10: Implement Downcasts
Unit 4:
Interfaces and Casting
174
179
189
193
200
Lesson: Defining and Implementing Local Interfaces
Exercise 11: Define and Implement a Local Interface
Lesson: Implementing Polymorphism Using Interfaces
Exercise 12: Implement Polymorphism Using Interfaces
Lesson: Integrating Class Models Using Interfaces
203
Exercise 13: Integrate Class Models Using Interfaces
© Copyright. All rights reserved.
v
223
Unit 5:
224
Lesson: Implementing Events in Local Classes
233
246
247
Exercise 14: Implement Events in Local Classes
Lesson: Implementing Events in Local Interfaces
Exercise 15: Implement Handling of Interface Events
261
Unit 6:
262
273
283
287
298
307
341
Unit 7:
ABAP Object-Oriented Examples
Lesson: Using the ABAP List Viewer (ALV)
Exercise 18: Implement the ALV Grid Control
Exercise 19: Implement a Dialog Box with the ALV Grid Control
Lesson: Describing Business Add-Ins (BAdIs)
Unit 8:
342
349
Global Classes in ABAP Development Tools
Lesson: Developing Eclipse-Based ABAP Programs
Exercise 20: Edit a Global Class and an Executable Program in
ABAP Development Tools (ADT)
Exercise 21: Use Refactoring Functions in ADT
363
373
Object-Oriented Repository Objects
Lesson: Creating Global Classes
Exercise 16: Implement a Global Class
Lesson: Defining and Implementing Global Interfaces
Exercise 17: Import and Implement a Global Interface
Lesson: Implementing Inheritance in Global Classes
308
315
321
330
Unit 9:
Class-Based Exceptions
374
Lesson: Explaining Class-Based Exceptions
380
389
403
411
Lesson: Defining and Raising Exceptions
Exercise 22: Implement Class-Based Exceptions
Lesson: Implementing Advanced Exception Handling Techniques
Exercise 23: Map Exceptions to Each Other
429
Unit 10:
430
437
451
453
463
467
476
479
490
vi
Object-Oriented Events
Unit Testing
Lesson: Unit Testing with ABAP Unit
Exercise 24: Execute an ABAP Unit Test
Unit 11:
Object-Oriented Design Patterns
Lesson: Implementing Advanced Object-Oriented Techniques
Lesson: Implementing the Singleton Pattern
Exercise 25: Implement the Singleton Pattern
Lesson: Implementing Factory Classes Using Friendship
Exercise 26: Implement a Factory Class Using Friendship
Lesson: Implementing Persistent Objects
© Copyright. All rights reserved.
503
Unit 12:
504
Runtime Type Services
Lesson: Using Runtime Type Identification (RTTI)
511
519
520
525
529
Exercise 27: Describe Object Type Properties at Runtime
Unit 13:
Creation of a Comprehensive Object-Oriented Application
Lesson: Developing a Comprehensive Object-Oriented Application
Exercise 28: Create an UML Class Diagram
Exercise 29: Develop a Comprehensive Object-Oriented
Application
© Copyright. All rights reserved.
vii
viii
© Copyright. All rights reserved.
Course Overview
TARGET AUDIENCE
This course is intended for the following audiences:
●
Application Consultant
●
Development Consultant
●
Developer
© Copyright. All rights reserved.
ix
x
© Copyright. All rights reserved.
UNIT 1
Introduction to Object-Oriented
Programming
Lesson 1
Explaining the Object-Oriented Programming Model
2
Lesson 2
Analyzing and Designing with Unified Modeling Language (UML)
Exercise 1: Create UML Diagrams
14
27
UNIT OBJECTIVES
●
Describe the differences between the procedural and object-oriented programming
models
●
Classify objects
●
Model in UML
© Copyright. All rights reserved.
1
Unit 1
Lesson 1
Explaining the Object-Oriented Programming
Model
LESSON OVERVIEW
This lesson provides an overview of the key concepts of ABAP programming using the objectoriented model.
Business Example
You need to explain the object-oriented programming model and its advantages to your
development project manager. For this reason, you require the following knowledge:
●
An understanding of procedural and object-oriented programming
●
An understanding of ABAP objects
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Describe the differences between the procedural and object-oriented programming
models
Evolution of ABAP
Figure 1: History of Selected Programming Languages
2
© Copyright. All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
As you can see from the figure, History of Selected Programming Languages, object-oriented
programming (such as the Simula 67 programming language), and the logical and procedural
programming models (as used in languages such as C and Pascal), were developed at about
the same time. Previously, COBOL and the procedural programming model dominated
enterprise application development. SAP used a macro assembler before ABAP was created.
Even today, many developers have more experience with procedural programming than with
object-oriented programming. Therefore, this introduction references the procedural model
when it explains object-oriented programming.
ABAP was created to improve reporting. It was independently developed as an in-house
programming language. It was influenced by other programming languages, such as COBOL
and Pascal. ABAP was then extended to form ABAP Objects. Therefore, ABAP Objects unite
object-oriented and procedural elements in one programming language. For the objectoriented programming part, ABAP Objects adopted object-oriented concepts for enterprise
application development in other languages (for example, Java, C++, and Smalltalk).
The Procedural Programming Model
Figure 2: Characteristics of the Procedural Programming Model
Global variables for a program contain data, while subroutines contain functions.
Every subroutine can access all global variables.
© Copyright. All rights reserved.
3
Unit 1: Introduction to Object-Oriented Programming
Components of a Procedural ABAP Program
Figure 3: Typical Procedural ABAP Program
A typical procedural ABAP program consists of type definitions and data declarations. The
data declarations describe the data structure the program uses when being executed.
It is possible to encapsulate logic in modularization units (for example, subroutines or
function modules). However, at the main program level, there is no special protection for the
global data objects. It is possible to read and change global variables from anywhere in the
program.
4
© Copyright. All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
Encapsulation of Data Using Function Groups
Figure 4: Encapsulating Data Using Function Groups
When a function module is called in the main program, its function group is loaded into the
internal session. The function group remains active until the main program finishes executing.
The system stores the main program and the called function groups in separate memory
areas. Even if the data objects of the function groups have the same data object names as
they do in the calling program, they do not share the same memory space.
Nothing is shared, even if the data objects of the function groups have the same name. It is
not possible to access the global data of a function group directly from the main program. You
can only call the function modules of the function groups from the main program. In turn, the
function modules can access other components, particularly the global data of their own
function group.
Encapsulation also uses the idea that the implementation of a service can be hidden from
other components of the system. The reason for this is that the other components cannot and
do not need to make assumptions about the internal status of the modularization unit. In this
way, the design of these other components is not dependent on the other modularization
units being implemented in a specific way.
A function group brings together data and functions. which manage the data. Encapsulated
access to data and services is one of the many concepts of the object-oriented programming
model. Therefore, this programming model and the procedural part of ABAP Objects support
this encapsulation. When implementing the Business Application Programming Interface
(BAPI), BAPIs are implemented as function modules and Business Objects are implemented
as function groups.
© Copyright. All rights reserved.
5
Unit 1: Introduction to Object-Oriented Programming
Function Groups
Figure 5: Example of a Function Group
The function group S_VEHICLE provides a user or client with the services Inc_speed,
dec_speed, and get_speed. These services are the interface of the function group. They all
have access to the global data object speed, which belongs to the function group.
Example of Using the Function Group
Figure 6: Example of Using the Function Group
The main program cannot access the data object speed of the function group directly.
6
© Copyright. All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
Multiple Instantiation
Figure 7: Several Instances of One Function Group
In order for the main program to work with several vehicles, there must be additional
programming and administrative effort. A function group can only refer to one vehicle at a
time.
Multiple Instantiation in Object-Oriented Programming
Figure 8: Multiple Instantiation in Object-Oriented Programming
The possibility to create several runtime instances using the same program context is one of
the key characteristics of object-oriented programming.
In this example, you will develop a program to create four vehicles, all of which have different
characteristics.
However, all the vehicles share the same data structure and the same set of functions. They
all have the ability to protect their data from outside access.
© Copyright. All rights reserved.
7
Unit 1: Introduction to Object-Oriented Programming
ABAP Main Memory and Encapsulation
Figure 9: ABAP Main Memory and Encapsulation
The features of encapsulation using function groups and subroutines are as follows:
●
You use modularization units to encapsulate functions and data.
●
You can work with the global data of the main program.
The features of encapsulation using objects are as follows:
●
You can use objects to encapsulate functions and data.
●
You can create multiple instances (objects).
You can perform multiple instantiation.
Objects are stored in the same internal session as the program in use. All data areas are
separate from each other, which keeps them protected.
8
© Copyright. All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
Data Management in Procedural and Object-Oriented Models
Figure 10: Data Management in Procedural and Object-Oriented Models
Unlike in procedural programming, using multiple instantiation in object-oriented
programming allows you to create a direct abstraction of a real object. Encapsulation was
systematically extended in this programming model.
ABAP Objects
The object-oriented concepts of ABAP Objects share concepts with other modern objectoriented languages, such as C++ or Java. Concepts that proved to be unsuccessful in other
languages were not included in ABAP Objects. On the other hand, ABAP Objects has helpful
language elements that C++ and Java do not have. Certain features of ABAP Objects only
exist because of the guaranteed upward compatibility of older ABAP language elements. The
difference between ABAP Objects and other object-oriented languages is the development
environment. You can use the entire range of functions of the ABAP Workbench with ABAP
Objects.
You can use ABAP Objects statements in procedural ABAP programs.
© Copyright. All rights reserved.
9
Unit 1: Introduction to Object-Oriented Programming
ABAP Objects as a Compatible Extension of ABAP
Figure 11: ABAP Objects as a Compatible Extension of ABAP
ABAP Objects is not a new language, but it was designed as a systematic extension of ABAP.
All of the extensions, including the old procedural parts, are upward compatible.
Type checks in the object-oriented contexts of ABAP Objects are stricter than those in the
procedural contexts.
To develop ABAP Objects, SAP cleaned up the ABAP language in the object-oriented
contexts. This means that obsolete statements lead to syntax errors.
Note:
It is advisable to avoid obsolete statements in the purely procedural environment,
because it creates safer and more flexible source code. However, because the
language is upward compatible, it is not possible to prevent the use of such
statements entirely.
For a list of obsolete language elements, refer to the ABAP keyword documentation. ABAP
prohibits the use of obsolete statements in the object-oriented context.
10
© Copyright. All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
Client/Server Relationship Between Objects
Figure 12: Client/Server Relationships Between Objects
Objects behave like client/server systems. When one object sends a message to another
object to ask it to behave in a certain way, the first object is defined as a client and the second
object is defined as a server.
To be able to separate requests and deliveries of services, the following conditions must be
met:
●
The client object must adhere to the protocol of the server object.
●
The protocol of server object must be clear enough for a potential client to follow it without
any problems.
Objects can perform both roles simultaneously. They can offer services to other objects while
requesting services at the same time.
In object-oriented programming, the services are distributed among the objects in such a way
that there are no redundancies and each object offers exactly those services it is responsible
for. If an object needs any other services, it requests them from other objects. This concept is
known as the principle of delegation.
Client/Server Relationship-Example
The developer should implement the common task of data retrieval and output over two
objects. One object is responsible for data retrieval and another object is responsible for
output. As long as the data retrieval object does not change its protocol, the developer can
alter the retrieval object’s internal implementation without changing the other object.
Alternatively, a different object could even replace the data retrieval object as long as the new
object uses the same protocol. These exchanges can also take place at runtime.
© Copyright. All rights reserved.
11
Unit 1: Introduction to Object-Oriented Programming
Additional Concepts of the Object-Oriented Programming Model
Figure 13: Additional Concepts of the Object-Oriented Programming Model
Some additional concepts in the object-oriented programming model are as follows:
●
Inheritance
Inheritance defines the implementation relationships between classes, so that one class
(subclass) adopts, adapts, or extends the structure and behavior of another class
(superclass).
●
Polymorphism
Polymorphism is when instances of classes respond differently to the same messages.
●
Event control
Instead of sending messages directly to specific objects, objects can also trigger events.
Then other objects react when the event is triggered.
Object-Oriented ABAP
Key Characteristics of the Object-Oriented Programming Model of ABAP Objects
●
Objects are a direct abstraction of the real world.
●
Objects are units made up of data and functions.
●
Processes can be implemented in a better way than in procedural programming.
Advantages of the Object-Oriented Programming Model Compared to the Procedural
Programming Model
12
●
Improved software structure and consistency in the development process
●
Reduced maintenance effort and less susceptibility to errors
© Copyright. All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
●
Better integration of the customer or user into the analysis, design, and maintenance
process
●
Simpler and more secure extension of the software
A standardized language is used in the various phases of software development (analysis,
specification, design, and implementation). Because of this standardization, communication
is easier when you change between phases.
The Software Development Process
Figure 14: The Software Development Process
In object-oriented programming, analysis and design decisions have a greater effect on the
implementation than they have on procedural programming. Therefore, use modeling
language or tools to standardize the analysis and design phase.
LESSON SUMMARY
You should now be able to:
●
Describe the differences between the procedural and object-oriented programming
models
© Copyright. All rights reserved.
13
Unit 1
Lesson 2
Analyzing and Designing with Unified Modeling
Language (UML)
LESSON OVERVIEW
This lesson explains how to develop an object-oriented solution to a business application
problem. It also explains how to classify your objects and define the relationships between
them using parts of Unified Modeling Language (UML) as a visual aid.
Business Example
You need to model a business application requirement before you implement the business
application. For this reason, you require the following knowledge:
●
An understanding of class diagrams
●
An understanding of object diagrams
●
An understanding of sequence diagrams
LESSON OBJECTIVES
After completing this lesson, you will be able to:
14
●
Classify objects
●
Model in UML
© Copyright. All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
Classification of Objects
Figure 15: Classifying Objects
Object-oriented programming views the real world as a collection of objects like airplanes,
cars, and people. Some of these objects are similar. In other words, objects can be described
in the same way if they use the same characteristics and exhibit the same behavior.
You can group all the characteristics and behaviors of these similar objects into one central
class. This class is used to describe every object derived from it. Therefore, a class is a
description of a quantity of objects that exhibit the same characteristics and the same
behavior.
For example, the vehicle (make x, ..., model n), is an object of class car. This object is a
concrete instance of its class. Therefore, an object has an identity, a status (number of
characteristic instances), and a behavior. The concepts of identity and status are different
from one another.
Identity is an attribute that distinguishes each object from all the other objects in its class.
Two objects can have identical attribute values, but these objects may not be identical. For
example, two coffee cups have the same height, diameter, handle, and color. Although their
statuses are identical, they are two different coffee cups.
Literature on the subject of object-oriented programming talks about instances. The term
instance means an object.
Note:
The literal meaning of instance is slightly more specific. It means that the instance
of a class is uniquely identifiable. In this chapter, you will make a distinction
between instance and object.
© Copyright. All rights reserved.
15
Unit 1: Introduction to Object-Oriented Programming
Classes as Abstraction Forms
Figure 16: Classes as Abstraction Forms
In a software context, abstractions are simplifications of complex relationships in the real
world. You can abstract a real, existing object to the dimensions needed to simulate a certain
section of the real world. In the figure, Classes as Abstraction Forms, vehicles are used to
explain the concept of abstraction. Software for a vehicle enthusiast and software for a scrap
merchant contain different abstractions (classes) for objects. Therefore, depending on the
type of abstraction, a class can contain different aspects of an object.
16
© Copyright. All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
Comparing Classes and Objects
Figure 17: Comparing Classes and Objects
An understanding of the relationship between classes and objects is a prerequisite for
completing the following lessons successfully.
Modeling in UML
UML is a globally standardized modeling language. You use it for the specification,
construction, visualization, and documentation of software system models.
UML enables uniform communication between users. UML is an industry standard and was
developed by the Object Management Group (OMG) in September 1997. SAP uses UML as
the company-wide standard for object-oriented modeling. For more information on the UML
specifications, see http://www.omg.org on the OMG homepage.
Class Diagrams
The different diagram types in UML represent different views of a system.
Three Diagram Types that Represent Different Views of a System
●
Class diagrams
Class diagrams show the relationships between the classes. This is a static view of a
model.
●
Behavior diagrams
Behavior diagrams show the sequence in which the objects relate to each other.
●
Component diagrams
© Copyright. All rights reserved.
17
Unit 1: Introduction to Object-Oriented Programming
Component diagrams show the organization and dependencies of components.
You can use ABAP Objects to implement class diagrams and behavior diagrams from a
programming perspective.
Component diagrams can be realized using the repository object package.
UML Representation of a Class
Figure 18: Representation of a Class
A class is represented by a rectangle in UML notation.
A class can be represented as follows:
●
Name of the class
●
Attributes of the class (optional)
●
Methods of the class (optional)
Attributes describe the data that can be stored in the objects of a class. They also determine
the status of an object. Methods describe the functions an object can perform. They
determine how an object behaves.
18
© Copyright. All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
Example of a Class Diagram
Figure 19: An Example of a Class Diagram
A class diagram describes all static relationships between the classes.
The basic forms of static relationships are as follows:
Association
A customer books a car at a rental car company.
Generalization and Specialization
A car, a bus, and a truck are all vehicles.
Note:
Classes can also be shown in class diagrams with their attributes and methods. In
this example of a class diagram, these attributes and methods have been omitted
to improve clarity.
© Copyright. All rights reserved.
19
Unit 1: Introduction to Object-Oriented Programming
Association
Figure 20: Association
An association describes a semantic relationship between classes. The specific relationship
between objects in these classes is known as an object link. Therefore, object links indicate
associations.
However, an association can also be recursive. In that case, the class would have a
relationship with itself.
In most cases, recursive associations are used to link two different objects in the same class.
Each association has two roles, one for each direction of the association. Each role can be
described by an association name. Each role has a cardinality that shows how many instances
can participate in this relationship. The multiplicity is the number of participating objects in
one class that have a relationship to an object in the other class. Like all other elements of the
model, cardinalities are dependent on the concrete situation being modeled.
In this example, you could also require a cardinality of at least one to indicate that only
someone who actually makes a booking becomes a customer of the rental car company. On
the other hand, the cardinality of any number would allow for a more general definition of a
customer.
Characteristics of association are as follows:
20
●
Represent an association between class symbols by drawing a line between them.
●
Specify the cardinality (also referred to as multiplicity) of the relationship at the end of
each line.
●
You must use arrows to indicate the navigation options.
●
You must write the association name in italics above the line. The name may contain an
arrow to indicate the read direction.
© Copyright. All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
●
Enter the role names at the end of the lines if the modeler defines roles for both partners.
Association with Roles-Example
Figure 21: Examples of Association with Roles
You can use role names at the end of the association lines to describe the relationships
between the classes involved. In the figure, Examples of Association with Roles, a person
could appear in the role of an employee or in the role of a company director.
In the recursive association shown in the figure, Examples of Association with Roles, the roles
of child and parent are defined using role names. Two instances of the LCL_PERSON class
have a relationship with each other and represent two roles.
© Copyright. All rights reserved.
21
Unit 1: Introduction to Object-Oriented Programming
Association Classes
Figure 22: Association Classes
If association is used to link two classes, then a special class can represent this relationship.
The characteristics of the relationship are described using the attributes of the association
class. A dotted line connects this class to the association line.
Aggregation and Composition
Figure 23: Aggregation and Composition
Aggregation and composition are specializations of association. Aggregation and composition
show that an object can contain other objects. The relationship can be described using the
phrases “consists of” or “is a part of”. For example, a car consists of wheels and an engine,
among other things.
22
© Copyright. All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
Aggregation and composition appear as a line between two classes. They are labeled using a
small rhombus. The rhombus indicates the aggregation or composition. Otherwise, the
notation conventions are the same used for associations.
Composition is a specialization of aggregation. Composition means that the contained object
cannot exist without the aggregation (for example, a car reservation cannot exist without the
car rental agency). Therefore, the cardinality of this kind of aggregate is at least one. The
lifetime of the individual parts is linked to the lifetime of the aggregate. This means that parts
are created either at the same time as the aggregate or after the aggregate, and are
destroyed, either at the same time as the aggregate, or before the aggregate. In UML
notation, a filled-in rhombus denotes composition.
Generalization and Specialization
Figure 24: Generalization and Specialization
Generalization and specialization relationships are always bidirectional. For example, the
class lcl_truck can be generalized as a special class of lcl_vehicle. Generalization and
specialization relationships are denoted by a triangular arrow. This arrow always points from
the specialized class to the generalized class. The level of generalization increases in the
direction of the arrow. Trees can be built up using these relationships.
© Copyright. All rights reserved.
23
Unit 1: Introduction to Object-Oriented Programming
Object Diagrams
Figure 25: An Object Diagram
An object diagram is a snapshot taken during program execution. It describes instances of
classes and the relationships between them. It is not a new type of diagram, but rather a
variant of the class diagram. It is only useful for representing a complex class diagram.
Explain the structure of the exercise on object diagrams. There are eight possible object
diagrams for the class diagram. The participants must determine the right and wrong object
diagrams in a multiple choice assessment.
The sequence diagrams complete the unit on modeling. You do not need to mention the
sequence diagrams for the rest of the course because there is no exercise for this concept.
24
© Copyright. All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
Sequence Diagrams
Figure 26: A Sequence Diagram
Sequence diagrams are used to show certain processes or situations.
A sequence diagram describes the sequence in which objects are processed and the
interaction they have with each other.
Sequence diagrams may show the following processes:
●
When objects are created or deleted
●
When objects exchange messages
In UML notation, the object lifeline is represented by dotted vertical lines with a box containing
the object name at the top. An X is used to indicate the end of the lifeline. The control focus
appears as a vertical rectangle on the object lifeline. The control focus shows the active period
of the object.
Possible statuses of an object are as follows:
●
An object is active when actions are executed.
●
An object is indirectly active if it is waiting for a subordinate procedure to end.
Messages appear as horizontal arrows between the object lines. The message is written
above the arrow in the Message (parameter) form. There are various ways to represent the
reply. In this example, it appears as a dotted returning arrow. You can also include a
description of the process and add comments to the object lifeline.
© Copyright. All rights reserved.
25
Unit 1: Introduction to Object-Oriented Programming
The Delegation Principle
Figure 27: Delegation Principle in Sequence Diagram
In delegation, two objects are involved in handling a request. The recipient of the request
assigns the execution of the request to a delegate. In this example, the driver (object driver)
sends the message get_fuel_level ( ) to the vehicle (object car). When the message is
received, the car sends a message to the tank (object tank) to find out what the tank contains.
In other words, the car delegates the task to the tank. If necessary, the car formats the
information containing the current value of the contents of the tank before passing it back to
the driver.
26
© Copyright. All rights reserved.
Unit 1
Exercise 1
Create UML Diagrams
Business Example
You are a modeler for an airline corporation that owns several airline carriers. You need to
create a simple model to manage your airline carriers and airplanes. For this reason, you must
be able to design simple UML class diagrams and model the basic objects.
In this airplane management model, you need to create relevant classes with attributes and
methods, and define the association between classes using suitable association types and
cardinalities.
Create a Class Diagram
1. Create a UML class diagram containing the following classes:
Table 1: Classes
Class Name
Description
LCL_CARRIER
For the Airline Companies
LCL_AIRPLANE
For Airplanes (unspecific)
LCL_PASSENGER_PLANE
For Passenger Planes
LCL_CARGO_PLANE
For Cargo Planes
2. Create appropriate attributes and methods for each class.
3. Define relationships between your classes and choose suitable association types.
4. Choose suitable cardinalities.
Distinguish Between Classes and Objects
As a modeler, decide whether the object diagrams in this unit are correct.
1. The figures, Possible Object Diagrams (1) and Possible Object Diagrams (2), show a class
diagram. Eight object diagrams are drawn for this class diagram. Decide whether each
object diagram is correct and select the corresponding checkbox to indicate your answer.
© Copyright. All rights reserved.
27
Unit 1: Introduction to Object-Oriented Programming
Figure 29: Possible Object Diagrams (1)
Figure 30: Possible Object Diagrams (2)
28
© Copyright. All rights reserved.
Unit 1
Solution 1
Create UML Diagrams
Business Example
You are a modeler for an airline corporation that owns several airline carriers. You need to
create a simple model to manage your airline carriers and airplanes. For this reason, you must
be able to design simple UML class diagrams and model the basic objects.
In this airplane management model, you need to create relevant classes with attributes and
methods, and define the association between classes using suitable association types and
cardinalities.
Create a Class Diagram
1. Create a UML class diagram containing the following classes:
Table 1: Classes
Class Name
Description
LCL_CARRIER
For the Airline Companies
LCL_AIRPLANE
For Airplanes (unspecific)
LCL_PASSENGER_PLANE
For Passenger Planes
LCL_CARGO_PLANE
For Cargo Planes
a) Use the model solution in the figure, Class Diagram for Exercise - CARRIER/
AIRPLANE, as a guide.
2. Create appropriate attributes and methods for each class.
a) Define the general attributes and methods for airplanes in LCL_AIRPLANE.
b) Use the model solution as a guide for the attributes and methods for all of the classes
required.
3. Define relationships between your classes and choose suitable association types.
a) A generalization and specialization relationship between LCL_AIRPLANE and
LCL_PASSENGER_PLANE or LCL_CARGO_PLANE seems to be appropriate. Create an
aggregation between LCL_AIRPLANE and LCL_CARRIER.
b) Use the model solution as a guide.
4. Choose suitable cardinalities.
a) You can use various cardinalities in this case. Use the relevant sections of the lesson
and the model solution as a guide.
© Copyright. All rights reserved.
29
Unit 1: Introduction to Object-Oriented Programming
Figure 28: Class Diagram for Exercise - CARRIER/AIRPLANE
Distinguish Between Classes and Objects
As a modeler, decide whether the object diagrams in this unit are correct.
1. The figures, Possible Object Diagrams (1) and Possible Object Diagrams (2), show a class
diagram. Eight object diagrams are drawn for this class diagram. Decide whether each
object diagram is correct and select the corresponding checkbox to indicate your answer.
Figure 29: Possible Object Diagrams (1)
30
© Copyright. All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
Figure 30: Possible Object Diagrams (2)
a) The object diagrams numbered 2, 4, 5, 6, and 8 are correct.
© Copyright. All rights reserved.
31
Unit 1: Introduction to Object-Oriented Programming
LESSON SUMMARY
You should now be able to:
32
●
Classify objects
●
Model in UML
© Copyright. All rights reserved.
Unit 1
Learning Assessment
1. Data and functions are kept separate in the procedural programming model.
Determine whether this statement is true or false.
X
True
X
False
2. What does multiple instantiation mean?
Choose the correct answer.
X
A Creating and managing runtime instances
X
B Implementing relationships between classes
X
C Creating instances of different classes
X
D Sending messages directly to specific objects by triggering events
3. Which of the following is a simplification of complex relationships in the real world?
Choose the correct answer.
X
A Inheritance
X
B Abstraction
X
C Encapsulation
X
D Event control
4. Which kind of UML diagram pays particular attention to the sequence in which objects
relate to each other?
Choose the correct answer.
X
A class
X
B behavior
X
C component
X
D object
© Copyright. All rights reserved.
33
Unit 1: Learning Assessment
5. You can group all characteristics and behaviors of similar objects into one central class.
Determine whether this statement is true or false.
34
X
True
X
False
© Copyright. All rights reserved.
Unit 1
Learning Assessment - Answers
1. Data and functions are kept separate in the procedural programming model.
Determine whether this statement is true or false.
X
True
X
False
2. What does multiple instantiation mean?
Choose the correct answer.
X
A Creating and managing runtime instances
X
B Implementing relationships between classes
X
C Creating instances of different classes
X
D Sending messages directly to specific objects by triggering events
3. Which of the following is a simplification of complex relationships in the real world?
Choose the correct answer.
X
A Inheritance
X
B Abstraction
X
C Encapsulation
X
D Event control
© Copyright. All rights reserved.
35
Unit 1: Learning Assessment - Answers
4. Which kind of UML diagram pays particular attention to the sequence in which objects
relate to each other?
Choose the correct answer.
X
A class
X
B behavior
X
C component
X
D object
5. You can group all characteristics and behaviors of similar objects into one central class.
Determine whether this statement is true or false.
36
X
True
X
False
© Copyright. All rights reserved.
UNIT 2
Fundamental Object-Oriented
Syntax
Lesson 1
Creating Local Classes
Exercise 2: Create Local Classes
39
53
Lesson 2
Creating Objects
Exercise 3: Create Objects
60
67
Lesson 3
Accessing Methods and Attributes
Exercise 4: Call Methods
71
77
Lesson 4
Implementing Constructors in Local Classes
Exercise 5: Create and Use Constructors
83
87
Lesson 5
Implementing Class Constructors in Local Classes
Exercise 6: Create and Use Static Constructors
95
99
UNIT OBJECTIVES
●
Define local classes
●
Define attributes
●
Create methods
●
Create objects
●
Call instance methods
●
Call static methods
●
Call functional methods
●
Access public attributes
© Copyright. All rights reserved.
37
Unit 2: Fundamental Object-Oriented Syntax
38
●
Create and use constructors
●
Create and use static constructors
© Copyright. All rights reserved.
Unit 2
Lesson 1
Creating Local Classes
LESSON OVERVIEW
This lesson provides an overview of local classes, attributes, and methods, which are the
fundamental object-oriented syntax elements.
Business Example
As a developer, you need to implement classes, objects, and associations of your model in
ABAP Objects.
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Define local classes
●
Define attributes
●
Create methods
Definition of Local Classes
Figure 31: An Example of a Class
The concept of classes is the foundation of object-oriented programming. A class can either
have public components or private components. You can access public components, such as
© Copyright. All rights reserved.
39
Unit 2: Fundamental Object-Oriented Syntax
methods and events, from outside a class. However, you cannot access private components,
for example data types and attributes, from outside a class.
The figure, An Example of a Class, shows a vehicle as an example of a class.
Characteristics of a Class
Figure 32: Defining Classes
Characteristics of a class in object-oriented programming are as follows:
40
●
A class is a set of objects that have the same structure and exhibit the same behavior.
●
A class provides a blueprint for all objects based on this class.
●
A class is made up of components, such as attributes, methods, events, constants, types,
and implemented interfaces, defined in the definition part. You can implement only
methods in the implementation part.
●
A class statement cannot be nested; that is, you cannot define a class within a class.
However, you can define local auxiliary classes for global classes.
© Copyright. All rights reserved.
Lesson: Creating Local Classes
Declaration of Attributes
Figure 33: An Example of Attributes
Attributes contain the data that can be stored in the objects of a class.
The types of attributes are as follows:
●
Elementary data object
●
Structured
●
Table-type
Attributes can consist of data types (local or global) or reference types.
Table 2: Attributes
The following table shows some examples of attributes for class LCL_VEHICLE:
Attributes
Description
MAKE
Vehicle make
MODEL
Type of model
SER_NO
Serial number
COLOR
Color
MAX_SEATS
Number of seats
R_MOTOR
Reference to class LCL_MOTOR
© Copyright. All rights reserved.
41
Unit 2: Fundamental Object-Oriented Syntax
Definition of Attributes, Types, and Constants
Figure 34: Definition of Attributes, Types, and Constants
In class DATA statements, you can only use the TYPE addition to refer to data types.
The LIKE addition is only allowed for local data objects or SY fields (for example, SY-DATE,
SY-UNAME, and so on).
The READ-ONLY addition indicates that a public attribute declared with DATA can be read
from outside. However, the attribute can only be changed by methods in the same class.
Currently, you can use the READ-ONLY addition in the public visibility section (PUBLIC
SECTION) of a class declaration or in an interface definition.
With TYPE REF TO, you can type an attribute as a reference.
The CONSTANTS statement is used within the class definition to define data objects that
have a constant value.
If you use the TYPES statement in the class definition, you are declaring a local type, which is
specific to this local class. You can create a local type to be used by one or more attributes
within the same class.
42
© Copyright. All rights reserved.
Lesson: Creating Local Classes
Visibility of Attributes
Figure 35: Visibility Sections of Attributes
Private attributes cannot be addressed directly from outside the class and are not visible to
outside users. You can protect attributes from outside access by characterizing them as
private attributes.
Note:
The friendship concept is an exception to this rule.
Public attributes are attributes that are visible to all users and can be directly accessed by
outside users.
Similarly, the constants and types defined by a class can be either private (for use inside the
class), or public, (accessible from outside the class). The public components of a class are
collectively known as the class interface.
Using the private visibility section is known as information hiding or encapsulation.
Encapsulation protects a class user by making changes to private components invisible to the
external user.
You can change the private components of a class without changing the interface. Assume
that the private components of a class are changed at some point with its interface remaining
the same, external users can still continue to work with the class as before. The external users
can only access the components through the interface of the class and will not notice the
internal implementation changes in the PRIVATE SECTIONS. However, when the public
components of a class change, every external user must take those changes into account.
Therefore, use public attributes sparingly, or avoid making incompatible changes to public
components altogether.
© Copyright. All rights reserved.
43
Unit 2: Fundamental Object-Oriented Syntax
Accessing Private Attributes
Figure 36: Defining Attributes
Private attributes are defined in the PRIVATE SECTION of a class. Public attributes are
defined in the PUBLIC SECTION of a class.
You can access private attributes using public methods that return or change the values of
the private attributes.
The slightly higher runtime requirement (method calls in comparison with direct value
assignment) is taken into account to satisfy the encapsulation concept.
The signature of a public method clearly establishes which values must or can be transferred,
and which types are to be assigned to these values. The signature of a public method forces
the external user to use the correct types. This method also ensures that all private attributes
are dealt consistently.
For the example, in the figure, Defining Attributes, if the MAKE and MODEL attributes are
public, it will be rsky because the user may forget to supply the attributes or specify
inconsistent attributes.
To solve this situation, you can use a public method, SET_TYPE, to ensure that proper values
are specified for both the attributes. A strict syntax check governs method calls, ensuring the
transfer of all required parameters. A method can perform a consistency check (to see if a
certain vehicle make produces the chosen model) and raise an exception if an error occurs.
To minimize runtime, individual attributes can be defined in the public visibility section. After
you have defined the attributes give them the READ-ONLY addition.
44
© Copyright. All rights reserved.
Lesson: Creating Local Classes
Static Attributes and Instance Attributes
Figure 37: Comparison of Instance Attributes with Static Attributes
Different kinds of attributes are as follows:
●
Instance attributes
Instance attributes exist once per object; that is, once per runtime instance of the class.
You define instance attributes with the syntax element, DATA.
●
Static attributes
Static attributes exist once for each class and are visible for all runtime instances in that
class. You define static attributes with the syntax element, CLASS-DATA.
Static attributes usually contain the following information that applies to all instances:
-
Types and constants
-
Central application data buffers
-
Administrative information, such as the instance counter
Technical literature refers to static attributes as “class attributes” (we use the CLASS-DATA
syntax element). As in C++ and Java, ABAP Objects uses the official term “static attribute”.
© Copyright. All rights reserved.
45
Unit 2: Fundamental Object-Oriented Syntax
Instance Attributes and Static Attributes in the Program Context
Figure 38: Instance Attributes and Static Attributes in the Program Context
The figure shows how the GV_N_O_VEHICLES static attribute is related to other program
elements in the memory. The static attribute exists only once in the loaded class, regardless
of the number of instances of LCL_VEHICLE. Therefore, you can say that instances share
static attributes.
Caution:
An integer data object is defined to count instances. It is not possible to find out
the number of created instances from the system.
46
© Copyright. All rights reserved.
Lesson: Creating Local Classes
Implementation of Methods
Figure 39: Syntax for Methods
Some of the key characteristics of methods are as follows:
●
Methods are internal procedures in classes that determine the behavior of the objects.
They can access all attributes in their class and can therefore change the state of
attributes.
●
Methods have a signature (interface parameters and exceptions) that enables them to
receive values when they are called and pass values back to the calling program.
●
Methods can have any number of IMPORTING, EXPORTING, and CHANGING parameters.
All parameters can be passed by value or reference.
Method Signature
Functional methods have one RETURNING parameter as well as importing parameters and
exceptions.
You can define all input parameters (IMPORTING and CHANGING parameters) as optional
parameters in the declaration using the OPTIONAL or DEFAULT addition. You do not need to
pass these parameters when you call the object. By using the OPTIONAL addition, the
parameter initializes according to type, while the DEFAULT addition allows you to enter a start
value.
Methods also support the SY-SUBRC return value, but only when you define the signature
exceptions with the use of EXCEPTIONS. Use the RAISING addition in place of EXCEPTIONS
to propagate class-based exceptions. The caller then handles these class-based exceptions
without evaluating the SY-SUBRC return value.
© Copyright. All rights reserved.
47
Unit 2: Fundamental Object-Oriented Syntax
Note:
Do not use both concepts together in one program.
Visibility of Methods
Figure 40: Visibility Sections of Methods
You assign methods to a visibility section to determine whether methods are called from
outside the class or from within the class. Private methods allow internal modularization.
48
© Copyright. All rights reserved.
Lesson: Creating Local Classes
Access to Private Methods
Figure 41: Accessing Private Methods
You define private methods in the PRIVATE SECTION and public methods in the PUBLIC
SECTION of a class.
It is not possible to access private methods directly from outside. However, a private method
can be called by a public method. In the figure, Accessing Private Methods, INIT_TYPE is a
private method that is called by the SET_TYPE public method. Defining this private auxiliary
method is useful because the instruction to initialize attributes may be used in other methods.
Note:
This is an introductory example. Later, you will learn more programming
techniques for evaluating formal parameters.
In a class, declarations of attribute names, method names, event names, constant names,
type names, and alias names share the same namespace. Additionally there is a local
namespace within methods. Local declarations within a method override declarations made in
the class.
© Copyright. All rights reserved.
49
Unit 2: Fundamental Object-Oriented Syntax
Static Methods and Instance Methods
Figure 42: Comparison of Instance Methods with Static Methods
Different kinds of methods are as follows:
●
Instance methods
You define instance methods using the METHODS syntax keyword.
●
Static methods
You define static methods using the CLASS-METHODS syntax keyword.
You define static methods at class level. In their implementation, you can only access
static components. This means that static methods do not need instances and can be
directly accessed through the class.
In the example shown in the figure Comparison of Instance Methods with Static Methods, the
static method GET_N_O_VEHICLES can only access the attribute GV_N_O_VEHICLES. The
method set_type is an instance method and can access all the attributes, both static and
instance.
You may see static methods referred to as class methods, in line with the CLASS-METHODS
keyword. In ABAP Objects, the official term is “static method”, as it is in C++ and Java.
50
© Copyright. All rights reserved.
Lesson: Creating Local Classes
Representation of Visibility in UML Class Diagrams
Figure 43: Visibility Sections and UML Notation
A UML class diagram lists the class name, class attributes, and methods.
The components in a class are shown in a UML diagram using the following notations:
●
Plus sign (+)
A plus sign (+) indicates public components (visible to all users).
●
Minus sign (–)
A minus sign (–) indicates private components (invisible to outside users).
●
Underline
An underlined component name sign (_) indicates static components.
Alternatively, the keywords public and private can be used as a prefix for methods.
A UML also allows manufacturers of modeling tools to create their own symbols for increased
visibility. The use of visibility characteristics is optional and is normally used only in models
that are nearing implementation.
© Copyright. All rights reserved.
51
Unit 2: Fundamental Object-Oriented Syntax
52
© Copyright. All rights reserved.
Unit 2
Exercise 2
Create Local Classes
Business Example
You are a developer for an airline corporation that owns several airline carriers. You need to
develop an object-oriented program that can manage airline carriers and their airlines. For
this reason, you must be able to define classes, attributes, and methods.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Solution: SAPBC401_BAS_S1.
Create a Program
1. Create an executable program, ZBC401_##_MAIN, without a TOP include.
Define and Implement a Local Class
Declare and implement a class for airplanes.
1. Within your main program, declare the local class LCL_AIRPLANE.
2. Define the following attributes:
Table 3: Attributes
Attribute Name and
Description
Data type
Attribute Type
MV_NAME
STRING
Private instance attribute
SAPLANE-PLANETYPE
Private instance attribute
(name of airplane)
MV_PLANETYPE
(type of airplane)
GV_N_O_AIRPLANES I
Private static attribute
(instance counter)
3. Define the public instance method SET_ATTRIBUTES for setting private instance
attributes.
Your method signature must consist of two suitable import parameters defined as
compatible with the two attributes.
4. Implement the public instance method SET_ATTRIBUTES in such a way that the two
instance attributes are set.
5. Define the public instance method DISPLAY_ATTRIBUTES for displaying private instance
attributes.
© Copyright. All rights reserved.
53
Unit 2: Fundamental Object-Oriented Syntax
6. Implement the public instance method DISPLAY_ATTRIBUTES so that the values of the
two instance attributes are output as an ABAP list. You can also output icons from the
type group ICON.
7. Define the public static method DISPLAY_N_O_AIRPLANES to display the private static
attribute.
8. Implement the public static method DISPLAY_N_O_AIRPLANES in such a way that the
value of the static attributes is output in the ABAP list.
Note:
So far, your class does not have a mechanism for ensuring that the instance
counter increases each time an object is created. Decide whether you want to
omit the counter for now, or to temporarily control increments using the
SET_ATTRIBUTES method.
9. To improve the list output, arrange the output in two columns, one for the descriptive text
and the other for the attribute values.
Hint:
Use addition AT<number> of the WRITE statement to place the output in a
given column. To facilitate later adjustments, do not use a literal for the
number. Define private constant C_POS_1 instead.
10. Save, check, and activate your code before running the program.
54
© Copyright. All rights reserved.
Unit 2
Solution 2
Create Local Classes
Business Example
You are a developer for an airline corporation that owns several airline carriers. You need to
develop an object-oriented program that can manage airline carriers and their airlines. For
this reason, you must be able to define classes, attributes, and methods.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Solution: SAPBC401_BAS_S1.
Create a Program
1. Create an executable program, ZBC401_##_MAIN, without a TOP include.
a) To start the Object Navigator, enter transaction code SE80.
b) In the unnamed dropdown list on the left of the screen, choose Package, specify the
name of the package ZBC401_##, and press Enter.
A Create Object dialog box displays.
c) To create the package, choose Yes.
A Create Package dialog box displays.
d) In the Create Package dialog box, enter a short description for the package and choose
Continue.
e) In the Prompt for transportable Workbench requestdialog box, choose Own Requests.
f) Choose a request and choose Continue.
g) Under Object Name, choose the package name and, from the context menu, choose
Create → Program.
h) In the Create Program dialog box, enter ZBC401_##_MAIN in the Program field, and
choose Continue.
i) In the ABAP: Program Attributes ZBC401_##_MAIN Changedialog box, enter a title for
the program. Leave all other default settings and choose Save.
j) In the Create Object Directory Entrydialog box, assign the program to your own
package, ZBC401_##, and choose Save.
k) In the Prompt for transportable Workbench requestdialog box, assign the program to
your own transport request and choose Continue.
The ABAP Editor: Change Report ZBC401_##_MAINscreen displays.
Define and Implement a Local Class
Declare and implement a class for airplanes.
1. Within your main program, declare the local class LCL_AIRPLANE.
© Copyright. All rights reserved.
55
Unit 2: Fundamental Object-Oriented Syntax
a) See the source code extract from the model solution.
2. Define the following attributes:
Table 3: Attributes
Attribute Name and
Description
Data type
Attribute Type
MV_NAME
STRING
Private instance attribute
SAPLANE-PLANETYPE
Private instance attribute
(name of airplane)
MV_PLANETYPE
(type of airplane)
GV_N_O_AIRPLANES I
Private static attribute
(instance counter)
a) See the source code extract from the model solution.
3. Define the public instance method SET_ATTRIBUTES for setting private instance
attributes.
Your method signature must consist of two suitable import parameters defined as
compatible with the two attributes.
a) See the source code extract from the model solution.
4. Implement the public instance method SET_ATTRIBUTES in such a way that the two
instance attributes are set.
a) See the source code extract from the model solution.
5. Define the public instance method DISPLAY_ATTRIBUTES for displaying private instance
attributes.
a) See the source code extract from the model solution.
6. Implement the public instance method DISPLAY_ATTRIBUTES so that the values of the
two instance attributes are output as an ABAP list. You can also output icons from the
type group ICON.
a) See the source code extract from the model solution.
Hint:
From SAP NetWeaver 7.02, you no longer need to load type groups
explicitly using the TYPE-POOLS statement.
7. Define the public static method DISPLAY_N_O_AIRPLANES to display the private static
attribute.
a) See the source code extract from the model solution.
8. Implement the public static method DISPLAY_N_O_AIRPLANES in such a way that the
value of the static attributes is output in the ABAP list.
a) See the source code extract from the model solution.
56
© Copyright. All rights reserved.
Lesson: Creating Local Classes
Note:
So far, your class does not have a mechanism for ensuring that the instance
counter increases each time an object is created. Decide whether you want to
omit the counter for now, or to temporarily control increments using the
SET_ATTRIBUTES method.
9. To improve the list output, arrange the output in two columns, one for the descriptive text
and the other for the attribute values.
Hint:
Use addition AT<number> of the WRITE statement to place the output in a
given column. To facilitate later adjustments, do not use a literal for the
number. Define private constant C_POS_1 instead.
a) See the source code extract from the model solution.
10. Save, check, and activate your code before running the program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
d) To run your program, on the application toolbar, choose the Direct Processingbutton.
Solution: SAPBC401_BAS_S1
REPORT sapbc401_bas_s1.
TYPE-POOLS icon.
*--------------------------------------------------------*
* CLASS lcl_airplane DEFINITION
*
*--------------------------------------------------------*
CLASS lcl_airplane DEFINITION.
PUBLIC SECTION.
METHODS:
set_attributes
IMPORTING
iv_name TYPE string
iv_planetype TYPE saplane-planetype,
display_attributes.
CLASS-METHODS:
display_n_o_airplanes.
PRIVATE SECTION.
CONSTANTS: c_pos_1 TYPE i VALUE 30.
DATA:
mv_name TYPE string,
mv_planetype TYPE saplane-planetype.
CLASS-DATA:
© Copyright. All rights reserved.
57
Unit 2: Fundamental Object-Oriented Syntax
gv_n_o_airplanes TYPE i.
ENDCLASS. "lcl_airplane DEFINITION
*--------------------------------------------------------*
* CLASS lcl_airplane IMPLEMENTATION
*
*--------------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
METHOD set_attributes.
mv_name = iv_name.
mv_planetype = iv_planetype.
* doesn't make sense so much, only in order to get an effect
* after calling display_n_o_airplanes:
gv_n_o_airplanes = gv_n_o_airplanes + 1.
ENDMETHOD. "set_attributes
METHOD display_attributes.
WRITE: / icon_ws_plane AS ICON,
/ 'Name of Airplane'(001) , AT c_pos_1 mv_name,
/ 'Type of Airplane:'(002), AT c_pos_1 mv_planetype.
ENDMETHOD. "display_attributes
METHOD display_n_o_airplanes.
SKIP.
WRITE: / 'Number of airplanes:'(ca1),
AT c_pos_1 gv_n_o_airplanes LEFT-JUSTIFIED.
ENDMETHOD. "display_n_o_airplanes
ENDCLASS. "lcl_airplane IMPLEMENTATION
58
© Copyright. All rights reserved.
Lesson: Creating Local Classes
LESSON SUMMARY
You should now be able to:
●
Define local classes
●
Define attributes
●
Create methods
© Copyright. All rights reserved.
59
Unit 2
Lesson 2
Creating Objects
LESSON OVERVIEW
This lesson explains the concept of creating objects.
Business Example
As a developer, you want to create multiple instances for the local class that you have created
in your ABAP Objects project. For this reason, you require an understanding of how to create
objects.
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Create objects
Objects as Instances of Classes
Figure 44: Overview of Instances of Classes
A class contains the generic description of an object and describes the characteristics that all
objects in that class have in common. During the program runtime, you use the class to create
discrete objects (instances) in the memory. This process is called instantiation. When the
class is accessed for the first time, it is loaded into memory.
60
© Copyright. All rights reserved.
Lesson: Creating Objects
Hint:
Although you can use classes and static components to write complete
applications, the reason for using object-oriented programming is to create and
work with runtime instances of classes.
Definition of Reference Variables
Figure 45: Definition of Reference Variables
The statement DATA go_vehicle1 TYPE REF TO lcl_vehicle defines a reference variable. This
variable can point to instances of the class lcl_vehicle. The initial value of a reference variable
is an empty reference, that is, the reference points to nothing at all.
© Copyright. All rights reserved.
61
Unit 2: Fundamental Object-Oriented Syntax
Creating Objects
Figure 46: Creating Objects
The CREATE OBJECT statement creates an object in the memory. The object attribute values
are initial or assigned according to the TYPE specification.
Reference Semantics of Object References
Figure 47: Reference Semantics of Object References
Object reference variables can be assigned to each other.
62
© Copyright. All rights reserved.
Lesson: Creating Objects
The figure, Reference Semantics of Object References, illustrates an example in which, after
the COMPUTE statement, GO_VEHICLE1 and GO_VEHICLE2 point to the same object.
The Garbage Collector
Figure 48: The Garbage Collector
Independent references are references that have not been defined within a class. The
Garbage Collector is a routine that starts automatically whenever the runtime system does
not have more important tasks to carry out.
In this example, the reference to object (2) LCL_OBJECT is initialized. However, there is no
subsequent reference point to this object. Therefore, the Garbage Collector deletes the
unreferenced object. Because there is no reference point to object (4) LCL_OBJECT, it is also
deleted.
You can use logical query IF go_obj IS INITIAL to determine whether go_obj contains the null
reference or does not point to any object.
Caution:
You can have object references and data references. In case of data references
do not use IS BOUND. In the case of object references, you can work with IS
INITIAL and IS BOUND.
© Copyright. All rights reserved.
63
Unit 2: Fundamental Object-Oriented Syntax
Multiple Instances
Figure 49: Reference Administration with Multiple Instantiation
To keep several objects from the same class in your program, you can define an internal table
with one column that contains the object references for this class. To maintain the objects in
the table, you can use statements for internal tables, such as APPEND, READ, or LOOP.
Example of Aggregation
Figure 50: Example of Aggregation
64
© Copyright. All rights reserved.
Lesson: Creating Objects
The objects in the LCL_WHEEL class have their own identity. You can create objects
regardless of the existence of an object in the LCL_VEHICLE class. References are transferred
to objects in class LCL_VEHICLE to create the desired association.
© Copyright. All rights reserved.
65
Unit 2: Fundamental Object-Oriented Syntax
66
© Copyright. All rights reserved.
Unit 2
Exercise 3
Create Objects
Business Example
As a developer, create instances of your airplane class and ensure that the references to the
objects are not lost.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S1.
Solution: SAPBC401_BAS_S2.
Define Variables
Define a reference variable.
1. Define a reference variable for the instances of your class LCL_AIRPLANE.
2. Define an internal table for buffering references to instances of the LCL_AIRPLANE class.
Create Objects
Create airplane objects.
1. Create several instances of local class LCL_AIRPLANE and buffer their references in the
internal table.
Hint:
Use the ABAP keyword START-OF-SELECTION to specify where the
executable part of the main program begins. Otherwise, the executable
statements are classified as unreachable by the syntax check.
2. Save, check, and activate your program.
3. Observe the execution of the program in the ABAP Debugger.
© Copyright. All rights reserved.
67
Unit 2
Solution 3
Create Objects
Business Example
As a developer, create instances of your airplane class and ensure that the references to the
objects are not lost.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S1.
Solution: SAPBC401_BAS_S2.
Define Variables
Define a reference variable.
1. Define a reference variable for the instances of your class LCL_AIRPLANE.
a) See the source code extract from the model solution.
2. Define an internal table for buffering references to instances of the LCL_AIRPLANE class.
a) See the source code extract from the model solution.
Create Objects
Create airplane objects.
1. Create several instances of local class LCL_AIRPLANE and buffer their references in the
internal table.
Hint:
Use the ABAP keyword START-OF-SELECTION to specify where the
executable part of the main program begins. Otherwise, the executable
statements are classified as unreachable by the syntax check.
a) See the source code extract from the model solution.
2. Save, check, and activate your program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
3. Observe the execution of the program in the ABAP Debugger.
68
© Copyright. All rights reserved.
Lesson: Creating Objects
a) To start the ABAP Debugger, choose Program → Execute → Debugging.
b) To debug your program, on the application toolbar, choose the Execute button, or
press F8.
Solution: SAPBC401_BAS_S2
REPORT sapbc401_bas_s2.
TYPE-POOLS icon.
*--------------------------------------------------------*
* CLASS lcl_airplane DEFINITION
*--------------------------------------------------------*
CLASS lcl_airplane DEFINITION.
*
...
ENDCLASS. "lcl_airplane DEFINITION
*--------------------------------------------------------*
* CLASS lcl_airplane IMPLEMENTATION
*--------------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
*
...
ENDCLASS. "lcl_airplane IMPLEMENTATION
DATA:
DATA:
go_airplane TYPE REF TO lcl_airplane.
gt_airplanes TYPE TABLE OF REF TO lcl_airplane.
START-OF-SELECTION.
CREATE OBJECT go_airplane.
APPEND go_airplane TO gt_airplanes.
CREATE OBJECT go_airplane.
APPEND go_airplane TO gt_airplanes.
CREATE OBJECT go_airplane.
APPEND go_airplane TO gt_airplanes.
© Copyright. All rights reserved.
69
Unit 2: Fundamental Object-Oriented Syntax
LESSON SUMMARY
You should now be able to:
●
70
Create objects
© Copyright. All rights reserved.
Unit 2
Lesson 3
Accessing Methods and Attributes
LESSON OVERVIEW
This lesson explains the process of accessing methods and attributes.
Business Example
As a developer, you need to explain the various ways of accessing methods and attributes of a
class. For this reason, you require the following knowledge:
●
An understanding of calling methods
●
An understanding of accessing attributes
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Call instance methods
●
Call static methods
●
Call functional methods
●
Access public attributes
Instance Method Calls
Figure 51: Calling Methods
© Copyright. All rights reserved.
71
Unit 2: Fundamental Object-Oriented Syntax
This section explains the use of classes and their instances, from the static connections of
various instances to their practical effects.
The example in the figure, Calling Methods, shows the shorter syntax for method calls in
which the CALL-METHOD prefix is omitted.
Syntax for Calling Instance Methods
Figure 52: Calling Instance Methods – Syntax
CALL METHOD ref->method_name is the syntax used to call instance methods. When calling
an instance method from within another instance method, you can omit the instance name
ref. The method is automatically executed for the current object.
A shorter syntax is also supported as of SAP NetWeaver Application Server (SAP NetWeaver
AS) 6.10. In this version, omit CALL METHOD and list the parameters in parentheses. There
must be no space before the parentheses, but there must be at least one space after the
parentheses. When you call a method that has only one import parameter, you can specify the
actual parameter in the parentheses without any other additions. When you call a method that
only has import parameters, you can omit the EXPORTING addition.
72
© Copyright. All rights reserved.
Lesson: Accessing Methods and Attributes
Static Method Calls
Figure 53: Calling Static Methods – Syntax
Use CALL METHOD classname=>method_name to call static methods (also referred to as
class methods).
Like static attributes, static methods are addressed with their class name, since they do not
need instances.
As with instance methods, when you call a static method from the class, you can omit the
class name; otherwise, the same rules apply here as for calling an instance method.
© Copyright. All rights reserved.
73
Unit 2: Fundamental Object-Oriented Syntax
Functional Method Calls
Figure 54: Functional Methods
Methods that have a RETURNING parameter are described as functional methods. The
RETURNING parameter must always be passed by value - RETURNING VALUE(...) - and not
by reference.
Note:
Prior to SAP NetWeaver 7.40, functional methods were only allowed IMPORTING
parameters and exceptions, in addition to their RETURNING parameter. From SAP
NetWeaver 7.40 onwards, they may have any number of EXPORTING and
CHANGING parameters.
You can directly call functional methods within the following expressions:
●
Logical expressions: IF, ELSEIF, WHILE, CHECK, WAIT
●
Arithmetic expressions and bit expressions: COMPUTE
●
Case conditions: CASE, WHEN
Note:
In SAP NetWeaver 7.02, the list of positions at which functional methods can be
used was extended considerably.
74
© Copyright. All rights reserved.
Lesson: Accessing Methods and Attributes
Functional Methods – Examples
Figure 55: Functional Methods – Examples
In the first part of the example, the two functional instance method calls represent the two
addends of an addition.
The second example shows the call of a functional static method in short form. The
GV_NUMBER data object is the actual parameter for the RETURNING parameter of the
method. The detailed syntax is as follows:
DATA gv_number TYPE i.
...
CALL METHOD lcl_vehicle=>get_n_o_vehicles
RECEIVING rv_count = gv_number.
© Copyright. All rights reserved.
75
Unit 2: Fundamental Object-Oriented Syntax
Access to Public Attributes
Figure 56: Accessing Public Attributes
You can access public attributes from outside the class in the same way as method calls. You
can access static attributes using CLASSNAME=>STATIC_ATTRIBUTE. Access instance
attributes with REF->INSTANCE_ATTRIBUTE.
76
© Copyright. All rights reserved.
Unit 2
Exercise 4
Call Methods
Business Example
As a developer, you need to fill the attributes of the objects with suitable values. You need to
know how to define and call methods.
Note:
This exercise uses the main program file ZBC401_##_MAIN, completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S2.
Solution: SAPBC401_BAS_S3.
Call Methods
Call the methods of your class.
1. Call the static method DISPLAY_N_O_AIRPLANES twice, once before and once after the
instantiations.
2. Use the SET_ATTRIBUTES method to set the attributes for all objects. Choose a unique
name for each airplane type (for example, 747-400). When assigning airplane types, use
the information in the SAPLANE table as a guide.
3. Display the attribute values for all airplanes in a loop in the ABAP list, using the
DISPLAY_ATTRIBUTES method.
Add Functional Methods
Add a functional method to your class.
1. Define the public static functional method GET_N_O_AIRPLANES in the class. The Method
signature must only consist of result parameter RV_COUNT, which must be an integer.
2. Call this method in the main program and output the value in the ABAP list.
3. Save, check, and activate your code before running the program.
© Copyright. All rights reserved.
77
Unit 2
Solution 4
Call Methods
Business Example
As a developer, you need to fill the attributes of the objects with suitable values. You need to
know how to define and call methods.
Note:
This exercise uses the main program file ZBC401_##_MAIN, completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S2.
Solution: SAPBC401_BAS_S3.
Call Methods
Call the methods of your class.
1. Call the static method DISPLAY_N_O_AIRPLANES twice, once before and once after the
instantiations.
a) See the source code extract from the model solution.
Note:
For reasons explained in the exercise, Create UML Diagrams, you might not
notice any effects at the moment.
2. Use the SET_ATTRIBUTES method to set the attributes for all objects. Choose a unique
name for each airplane type (for example, 747-400). When assigning airplane types, use
the information in the SAPLANE table as a guide.
a) See the source code extract from the model solution.
3. Display the attribute values for all airplanes in a loop in the ABAP list, using the
DISPLAY_ATTRIBUTES method.
a) See the source code extract from the model solution.
Add Functional Methods
Add a functional method to your class.
1. Define the public static functional method GET_N_O_AIRPLANES in the class. The Method
signature must only consist of result parameter RV_COUNT, which must be an integer.
a) See the source code extract from the model solution.
2. Call this method in the main program and output the value in the ABAP list.
78
© Copyright. All rights reserved.
Lesson: Accessing Methods and Attributes
a) See the source code extract from the model solution.
3. Save, check, and activate your code before running the program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
d) To run your program, on the application toolbar, choose the Direct Processingbutton.
Solution: SAPBC401_BAS_S3
Report SAPBC401_BAS_S3.
TYPE-POOLS icon.
*----------------------------------------------*
* CLASS lcl_airplane DEFINITION
*----------------------------------------------*
CLASS lcl_airplane DEFINITION.
PUBLIC SECTION.
METHODS:
set_attributes IMPORTING iv_name TYPE string
iv_planetype TYPE saplane-planetype,
display_attributes.
CLASS-METHODS:
display_n_o_airplanes,
get_n_o_airplanes RETURNING value(rv_count) TYPE i.
PRIVATE SECTION.
CONSTANTS:
c_pos_1 TYPE i VALUE 30.
DATA: mv_name TYPE string,
mv_planetype TYPE saplane-planetype.
CLASS-DATA: gv_n_o_airplanes TYPE i.
ENDCLASS. "lcl_airplane DEFINITION
*----------------------------------------------*
* CLASS lcl_airplane IMPLEMENTATION
*----------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
METHOD
set_attributes.
mv_planetype = iv_planetype.
* doesn't make sense so much,
* only in order to get an effect
* after calling display_n_o_airplanes:
gv_n_o_airplanes = gv_n_o_airplanes + 1.
© Copyright. All rights reserved.
79
Unit 2: Fundamental Object-Oriented Syntax
ENDMETHOD. "set_attributes
METHOD
display_attributes.
WRITE:
/ icon_ws_plane AS ICON,
/ 'Name of Airplane'(001) , AT c_pos_1 mv_name,
/ 'Type of Airplane:'(002), AT c_pos_1 mv_planetype.
ENDMETHOD. "display_attributes
METHOD display_n_o_airplanes.
SKIP.
WRITE:
/ 'Number of airplanes:'(ca1),
AT c_pos_1 gv_n_o_airplanes LEFT-JUSTIFIED.
ENDMETHOD. "display_n_o_airplanes
METHOD get_n_o_airplanes.
rv_count = gv_n_o_airplanes.
ENDMETHOD. "get_n_o_airplanes
ENDCLASS. "lcl_airplane IMPLEMENTATION
DATA:
go_airplane TYPE REF TO lcl_airplane,
gt_airplanes TYPE TABLE OF REF TO lcl_airplane,
gv_count TYPE i.
START-OF-SELECTION.
lcl_airplane=>display_n_o_airplanes( ).
CREATE OBJECT go_airplane.
APPEND go_airplane TO gt_airplanes.
go_airplane->set_attributes( iv_name = 'LH Berlin'
iv_planetype = 'A321' ).
CREATE OBJECT go_airplane.
APPEND go_airplane TO gt_airplanes.
go_airplane->set_attributes( iv_name = 'AA New York'
iv_planetype = '747-400' ).
CREATE OBJECT go_airplane.
APPEND go_airplane TO gt_airplanes.
go_airplane->set_attributes( iv_name = 'US Hercules'
iv_planetype = '747-200F' ).
LOOP AT gt_airplanes INTO go_airplane.
go_airplane->display_attributes( ).
ENDLOOP.
*
*
*
*
*
*
80
long syntax for functional call:
CALL METHOD lcl_airplane=>get_n_o_airplanes
RECEIVING
rv_count = gv_count.
a little bit shorter:
© Copyright. All rights reserved.
Lesson: Accessing Methods and Attributes
* lcl_airplane=>get_n_o_airplanes( RECEIVING rv_count =
* gv_count ).
*
* the shortest syntax for functional call:
gv_count = lcl_airplane=>get_n_o_airplanes( ).
SKIP 2.
WRITE: / 'Number of airplanes'(ca1), gv_count.
© Copyright. All rights reserved.
81
Unit 2: Fundamental Object-Oriented Syntax
LESSON SUMMARY
You should now be able to:
82
●
Call instance methods
●
Call static methods
●
Call functional methods
●
Access public attributes
© Copyright. All rights reserved.
Unit 2
Lesson 4
Implementing Constructors in Local Classes
LESSON OVERVIEW
This lesson explains the implementation of constructor methods in local classes.
Business Example
As a developer, you must explain the creation and use of instance constructors for the class in
your ABAP Objects project. For this reason, you require the following knowledge:
●
An understanding of instance constructors
●
An understanding of how to use instance constructors
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Create and use constructors
Instance Constructor
Figure 57: Instance Constructor
There are two types of methods in ABAP Objects. ABAP Objects can be called implicitly or
explicitly with the CALL METHOD syntax. Constructors are the first type of method.
© Copyright. All rights reserved.
83
Unit 2: Fundamental Object-Oriented Syntax
The instance constructor is a special instance method in a class and is always named
CONSTRUCTOR. The constructor is automatically called at runtime with the CREATE
OBJECT statement.
When defining constructors, always consider the following points:
●
No class can have more than one instance constructor.
●
A constructor must be defined in the public area.
●
The constructor signature can only include importing parameters and exceptions.
●
When exceptions are raised in the constructor, no instances are created and no main
memory space is occupied.
●
Except for one unique case, you cannot call the constructor explicitly.
Note:
There is no destructor in ABAP Objects; that is, there is no instance method that is
automatically called from the memory immediately before the object is deleted.
The corresponding comments in the SAP Library and the menu paths outside the
ABAP Workbench are only contained in internal system calls.
Constructor – Example
Figure 58: Constructor – Example
After the instantiation of a class, a constructor is necessary when some of the following
conditions occur:
●
84
You must allocate resources.
© Copyright. All rights reserved.
Lesson: Implementing Constructors in Local Classes
●
You must initialize attributes that cannot be covered by the VALUE addition to the DATA
statement.
●
You modify static attributes.
●
You must inform other objects about the object creation.
© Copyright. All rights reserved.
85
Unit 2: Fundamental Object-Oriented Syntax
86
© Copyright. All rights reserved.
Unit 2
Exercise 5
Create and Use Constructors
Business Example
Define and implement instance constructors. Create instances of classes that contain an
instance constructor. Define, raise, and handle classical, non-class-based exceptions.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S3.
Solution: SAPBC401_BAS_S4
.
Define an Instance Constructor
1. Define a constructor with a suitable signature for the instances of your class
LCL_AIRPLANE.
2. Implement the constructor in a way that the two instance attributes are set and instance
counter GV_N_O_AIRPLANES is increased by one.
3. Remove the definition and implementation of method SET_ATTRIBUTES to ensure that an
attribute of instance can be set only once during its creation.
Create New Objects
Create airplane objects.
1. Your CREATE OBJECT statements from the previous exercise are now syntactically
incorrect. Adapt and correct them.
2. Remove calls of the SET_ATTRIBUTES method.
3. Save, check, and activate your program.
4. Follow the execution of the program in the ABAP Debugger.
Set Instance Attributes to Access a Database Table
Define additional instance attributes with technical information about the airplane. Set these
attributes in your constructor by accessing database table SAPLANE. Raise an exception if
the specified plane type is not found in the database.
1. In the class LCL_AIRPLANE, define private instance attributes MV_WEIGHT (data type
SAPLANE-WEIGHT) and MV_TANKCAP (data type SAPLANE-TANKCAP).
2. In the method DISPLAY_ATTRIBUTES, use WRITE statements to output the additional
attributes.
© Copyright. All rights reserved.
87
Unit 2: Fundamental Object-Oriented Syntax
3. Extend the definition of the instance constructor by adding a classical exception that is not
class-based, WRONG_PLANETYPE.
4. Extend the implementation of the constructor. Read a single record from database table
SAPLANE for the specified plane type and set new attributes accordingly.
Raise the exception when no data is found for the given plane type.
5. Adjust the CREATE OBJECT statements so that you handle the exception. Only store the
object reference in your table when the creation is successful.
6. Save, check, and activate your program.
7. Follow the execution of the program in the ABAP Debugger. For test purposes, specify a
nonexisting airplane type to see how the exception handling works.
88
© Copyright. All rights reserved.
Unit 2
Solution 5
Create and Use Constructors
Business Example
Define and implement instance constructors. Create instances of classes that contain an
instance constructor. Define, raise, and handle classical, non-class-based exceptions.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S3.
Solution: SAPBC401_BAS_S4
.
Define an Instance Constructor
1. Define a constructor with a suitable signature for the instances of your class
LCL_AIRPLANE.
a) See the source code extract from the model solution.
2. Implement the constructor in a way that the two instance attributes are set and instance
counter GV_N_O_AIRPLANES is increased by one.
a) See the source code extract from the model solution.
3. Remove the definition and implementation of method SET_ATTRIBUTES to ensure that an
attribute of instance can be set only once during its creation.
a) See the source code extract from the model solution.
Create New Objects
Create airplane objects.
1. Your CREATE OBJECT statements from the previous exercise are now syntactically
incorrect. Adapt and correct them.
a) See the source code extract from the model solution.
2. Remove calls of the SET_ATTRIBUTES method.
a) See the source code extract from the model solution.
3. Save, check, and activate your program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
© Copyright. All rights reserved.
89
Unit 2: Fundamental Object-Oriented Syntax
4. Follow the execution of the program in the ABAP Debugger.
a) To start the ABAP Debugger, choose Program → Execute → Debugging.
b) To debug your program, on the application toolbar, choose the Execute button, or
press F8.
Set Instance Attributes to Access a Database Table
Define additional instance attributes with technical information about the airplane. Set these
attributes in your constructor by accessing database table SAPLANE. Raise an exception if
the specified plane type is not found in the database.
1. In the class LCL_AIRPLANE, define private instance attributes MV_WEIGHT (data type
SAPLANE-WEIGHT) and MV_TANKCAP (data type SAPLANE-TANKCAP).
a) See the source code extract from the model solution.
2. In the method DISPLAY_ATTRIBUTES, use WRITE statements to output the additional
attributes.
a) See the source code extract from the model solution.
3. Extend the definition of the instance constructor by adding a classical exception that is not
class-based, WRONG_PLANETYPE.
a) See the source code extract from the model solution.
4. Extend the implementation of the constructor. Read a single record from database table
SAPLANE for the specified plane type and set new attributes accordingly.
Raise the exception when no data is found for the given plane type.
a) See the source code extract from the model solution.
5. Adjust the CREATE OBJECT statements so that you handle the exception. Only store the
object reference in your table when the creation is successful.
a) See the source code extract from the model solution.
6. Save, check, and activate your program.
7. Follow the execution of the program in the ABAP Debugger. For test purposes, specify a
nonexisting airplane type to see how the exception handling works.
a) To start the ABAP Debugger, choose Program → Execute → Debugging.
b) To debug your program, on the application toolbar, choose the Execute button, or
press F8.
Solution: SAPBC401_BAS_S4
REPORT
sapbc401_bas_s4.
TYPE-POOLS icon.
*-------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*
*-------------------------------------------------*
CLASS lcl_airplane DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
90
© Copyright. All rights reserved.
Lesson: Implementing Constructors in Local Classes
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
EXCEPTIONS
wrong_planetype,
display_attributes.
CLASS-METHODS:
display_n_o_airplanes,
get_n_o_airplanes
RETURNING value(rv_count) TYPE i.
PRIVATE SECTION.
CONSTANTS:
c_pos_1 TYPE i VALUE 30.
DATA:
mv_name
mv_planetype
mv_weight
mv_tankcap
TYPE
TYPE
TYPE
TYPE
string,
saplane-planetype,
saplane-weight,
saplane-tankcap.
CLASS-DATA:
gv_n_o_airplanes TYPE i.
ENDCLASS.
"lcl_airplane DEFINITION
*--------------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*
*--------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
METHOD constructor.
DATA: ls_planetype TYPE saplane.
mv_name
= iv_name.
mv_planetype = iv_planetype.
SELECT SINGLE * FROM saplane
INTO ls_planetype
WHERE planetype = iv_planetype.
IF sy-subrc <> 0.
RAISE wrong_planetype.
ELSE.
mv_weight = ls_planetype-weight.
mv_tankcap = ls_planetype-tankcap.
gv_n_o_airplanes = gv_n_o_airplanes + 1.
ENDIF.
ENDMETHOD.
"constructor
METHOD display_attributes.
WRITE:
/ icon_ws_plane AS ICON,
/ 'Name of Airplane'(001) , AT c_pos_1 mv_name,
/ 'Type of Airplane:'(002), AT c_pos_1 mv_planetype,
/ 'Weight:'(003),
AT c_pos_1 mv_weight
© Copyright. All rights reserved.
91
Unit 2: Fundamental Object-Oriented Syntax
LEFT-JUSTIFIED,
/ 'Tank capacity:'(004),
LEFT-JUSTIFIED.
ENDMETHOD.
AT c_pos_1 mv_tankcap
"display_attributes
METHOD display_n_o_airplanes.
SKIP.
WRITE:
/ 'Number of airplanes:'(ca1),
AT c_pos_1 gv_n_o_airplanes LEFT-JUSTIFIED.
ENDMETHOD.
"display_n_o_airplanes
METHOD get_n_o_airplanes.
rv_count = gv_n_o_airplanes.
ENDMETHOD.
"get_n_o_airplanes
ENDCLASS.
"lcl_airplane IMPLEMENTATION
DATA:
go_airplane TYPE REF TO lcl_airplane,
gt_airplanes TYPE TABLE OF REF TO lcl_airplane,
gv_count
TYPE i.
START-OF-SELECTION.
*******************
lcl_airplane=>display_n_o_airplanes( ).
CREATE OBJECT go_airplane
EXPORTING
iv_name
= 'LH Berlin'
iv_planetype
= 'A321'
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
APPEND go_airplane TO gt_airplanes.
ENDIF.
CREATE OBJECT go_airplane
EXPORTING
iv_name
= 'AA New York'
iv_planetype
= '747-400'
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
APPEND go_airplane TO gt_airplanes.
ENDIF.
CREATE OBJECT go_airplane
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
APPEND go_airplane TO gt_airplanes.
ENDIF.
LOOP AT gt_airplanes INTO go_airplane.
go_airplane->display_attributes( ).
92
© Copyright. All rights reserved.
Lesson: Implementing Constructors in Local Classes
ENDLOOP.
gv_count = lcl_airplane=>get_n_o_airplanes( ).
SKIP 2.
WRITE: / 'Number of airplanes'(ca1), gv_count.
© Copyright. All rights reserved.
93
Unit 2: Fundamental Object-Oriented Syntax
LESSON SUMMARY
You should now be able to:
●
94
Create and use constructors
© Copyright. All rights reserved.
Unit 2
Lesson 5
Implementing Class Constructors in Local
Classes
LESSON OVERVIEW
This lesson explains the creation and use of static constructors and self-references.
Business Example
As a developer, you need to explain the creation and use of static constructors for the classes
in your ABAP Objects project.
●
An understanding of static constructors
●
An understanding of self-reference
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Create and use static constructors
Static Constructor
Figure 59: Example of a Static Constructor
© Copyright. All rights reserved.
95
Unit 2: Fundamental Object-Oriented Syntax
The static constructor is a special static method and is always named
CLASS_CONSTRUCTOR. The static constructor is executed only once per program.
The static constructor is called by the system automatically before the class is first accessed
and before the first execution of the following actions:
●
When an instance of the class (CREATE OBJECT) is created.
●
When a static attribute of the class is accessed.
●
When a static method of the class is called.
●
When an event handler method for an event in the class is being registered.
When you define static constructors, always consider the following points:
●
Each class does not have more than one static constructor.
●
The static constructor must be defined in the public area.
●
The static constructor does not have any parameters or exceptions.
●
The static constructor cannot be called explicitly.
Self-Reference
Figure 60: Self-Reference
In some cases, you must also have a self-reference available. In ABAP Objects, self-references
are always predefined, but they are only useful and syntactically available in certain contexts.
You can address an object itself by using the predefined reference variable ME within its
instance methods. You are not required to use me-> as a prefix in such cases, but you can
use it to improve readability.
However, you must use the prefix me-> when distinguishing between local data objects and
instance attributes with the same name.
96
© Copyright. All rights reserved.
Lesson: Implementing Class Constructors in Local Classes
An important use of self reference is when you call a foreign method and a client object is
required to export a reference to itself, you can then use ME as an actual parameter with
EXPORTING or CHANGING.
© Copyright. All rights reserved.
97
Unit 2: Fundamental Object-Oriented Syntax
98
© Copyright. All rights reserved.
Unit 2
Exercise 6
Create and Use Static Constructors
Business Example
For performance reasons, you do not want to access the database each time an instance is
created. Therefore, read all the data just once in the static constructor and store it in a static
attribute.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S4
.
Solution: SAPBC401_BAS_S5.
Use the Static Constructor to Buffer Data
Use a static attribute to buffer data from database table SAPLANE. Fill it using the static
constructor.
1. Define internal table GT_PLANETYPES as a private static attribute.
To specify the type for the GT_PLANETYPES internal table, define private table type
TY_PLANETYPES in the class definition.
Use the PLANETYPE field as a key for the internal table.
2. Define a static constructor in the LCL_AIRPLANE class.
3. Implement the constructor in such a way that the GT_PLANETYPES internal table is filled
with all rows from the SAPLANE database table. You can use the ARRAY FETCH technique
for this purpose.
4. Save, check, and activate your program.
5. Use the ABAP Debugger to ensure that the static constructor is called correctly and that
the internal table is filled in the main program.
6. Where is the static constructor called in the main program?
Declare and Implement a Private Static Method
Declare and implement a private static method to derive the weight and tank capacity of one
plane type from the GT_PLANETYPES table.
© Copyright. All rights reserved.
99
Unit 2: Fundamental Object-Oriented Syntax
1. Within the LCL_AIRPLANE class, define private static method
GET_TECHNICAL_ATTRIBUTES.
The signature must consist of one import parameter for the airplane type and two export
parameters for weight and tank capacity. Use transparent table SAPLANE as a guide for
specifying the types of these formal parameters.
The signature must contain a classical exception, which is raised when no data is found for
the specified airplane type. Use a non-class exception.
2. Implement the method in such a way that the values for export parameters are
determined by a single-record access to internal table GT_PLANETYPES.
When the table does not contain any values for the airplane type, the method raises an
exception.
Note:
The correct unit of measure must also be selected and exported. However,
because of time constraints, you do not need to include it in this exercise.
Replace the Database Access in the Instance Constructor
Replace the database access in the instance constructor calling of method
GET_TECHNICAL_ATTRIBUTES.
1. Is it possible to call the new method from the main program? Why is this?
2. Call method GET_TECHNICAL_ATTRIBUTES from the constructor to obtain additional
technical data. Depending on the outcome, set the corresponding private attributes or
raise the exception of the constructor.
3. Save, check, and activate your program.
4. Observe the execution of the program in the ABAP Debugger.
5. Which alternative solutions could be used to solve the tasks?
100
© Copyright. All rights reserved.
Unit 2
Solution 6
Create and Use Static Constructors
Business Example
For performance reasons, you do not want to access the database each time an instance is
created. Therefore, read all the data just once in the static constructor and store it in a static
attribute.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S4
.
Solution: SAPBC401_BAS_S5.
Use the Static Constructor to Buffer Data
Use a static attribute to buffer data from database table SAPLANE. Fill it using the static
constructor.
1. Define internal table GT_PLANETYPES as a private static attribute.
To specify the type for the GT_PLANETYPES internal table, define private table type
TY_PLANETYPES in the class definition.
Use the PLANETYPE field as a key for the internal table.
a) See the source code extract from the model solution.
2. Define a static constructor in the LCL_AIRPLANE class.
a) See the source code extract from the model solution.
3. Implement the constructor in such a way that the GT_PLANETYPES internal table is filled
with all rows from the SAPLANE database table. You can use the ARRAY FETCH technique
for this purpose.
a) See the source code extract from the model solution.
4. Save, check, and activate your program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
5. Use the ABAP Debugger to ensure that the static constructor is called correctly and that
the internal table is filled in the main program.
a) To start the ABAP Debugger, choose Program → Execute → Debugging.
© Copyright. All rights reserved.
101
Unit 2: Fundamental Object-Oriented Syntax
b) To debug the program, on the application toolbar, choose Execute, or press F8.
6. Where is the static constructor called in the main program?
When the class is accessed for the first time which is when the DISPLAY_N_O_AIRPLANES
method is called. It runs before the DISPLAY_N_O_AIRPLANES method is executed.
Declare and Implement a Private Static Method
Declare and implement a private static method to derive the weight and tank capacity of one
plane type from the GT_PLANETYPES table.
1. Within the LCL_AIRPLANE class, define private static method
GET_TECHNICAL_ATTRIBUTES.
The signature must consist of one import parameter for the airplane type and two export
parameters for weight and tank capacity. Use transparent table SAPLANE as a guide for
specifying the types of these formal parameters.
The signature must contain a classical exception, which is raised when no data is found for
the specified airplane type. Use a non-class exception.
a) See the source code extract from the model solution.
2. Implement the method in such a way that the values for export parameters are
determined by a single-record access to internal table GT_PLANETYPES.
When the table does not contain any values for the airplane type, the method raises an
exception.
a) See the source code extract from the model solution.
Note:
The correct unit of measure must also be selected and exported. However,
because of time constraints, you do not need to include it in this exercise.
Replace the Database Access in the Instance Constructor
Replace the database access in the instance constructor calling of method
GET_TECHNICAL_ATTRIBUTES.
1. Is it possible to call the new method from the main program? Why is this?
You can only call the new method from the main program if the method is public. Because
the new method in this case is a private method, it can only be called from within the
LCL_AIRPLANE class.
2. Call method GET_TECHNICAL_ATTRIBUTES from the constructor to obtain additional
technical data. Depending on the outcome, set the corresponding private attributes or
raise the exception of the constructor.
a) See the source code extract from the model solution.
3. Save, check, and activate your program.
4. Observe the execution of the program in the ABAP Debugger.
5. Which alternative solutions could be used to solve the tasks?
102
© Copyright. All rights reserved.
Lesson: Implementing Class Constructors in Local Classes
a) Define GET_TECHNICAL_ATTRIBUTES as instance method without the PLANETYPE
import parameter.
If the method is defined as an instance method, it can access the MV_PLANETYPE
attribute directly (as ME->MV_PLANETYPES). In this case, the import parameter is not
needed.
b) Do not use a method to read GT_PLANETYPES.
In the instance constructor, you can access the class attribute GT_PLANETYPES
directly (using ME->GT_PLANETYPES).
Solution: SAPBC401_BAS_S5
REPORT
sapbc401_bas_s5.
TYPE-POOLS icon.
*-------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*-------------------------------------------------*
CLASS lcl_airplane DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
EXCEPTIONS
wrong_planetype,
display_attributes.
CLASS-METHODS:
class_constructor,
display_n_o_airplanes,
get_n_o_airplanes
RETURNING value(rv_count) TYPE i.
PRIVATE SECTION.
TYPES:
ty_planetypes TYPE STANDARD TABLE OF saplane
WITH NON-UNIQUE KEY planetype.
CONSTANTS:
c_pos_1 TYPE i VALUE 30.
DATA:
mv_name
mv_planetype
mv_weight
mv_tankcap
TYPE
TYPE
TYPE
TYPE
string,
saplane-planetype,
saplane-weight,
saplane-tankcap.
CLASS-DATA:
gv_n_o_airplanes TYPE i,
gt_planetypes
TYPE ty_planetypes.
CLASS-METHODS:
get_technical_attributes
IMPORTING
© Copyright. All rights reserved.
103
Unit 2: Fundamental Object-Oriented Syntax
iv_type
TYPE saplane-planetype
EXPORTING
ev_weight
TYPE saplane-weight
ev_tankcap TYPE saplane-tankcap
EXCEPTIONS
wrong_planetype.
ENDCLASS.
"lcl_airplane DEFINITION
*------------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
METHOD class_constructor.
SELECT * FROM saplane INTO TABLE gt_planetypes.
ENDMETHOD.
"class_constructor
*
METHOD constructor.
DATA: ls_planetype TYPE saplane.
mv_name
= iv_name.
mv_planetype = iv_planetype.
*
*
*
*
*
SELECT SINGLE * FROM saplane
INTO ls_planetype
WHERE planetype = iv_planetype.
get_technical_attributes(
EXPORTING
iv_type = iv_planetype
IMPORTING
ev_weight = mv_weight
ev_tankcap = mv_tankcap
EXCEPTIONS
wrong_planetype = 1 ).
IF sy-subrc <> 0.
RAISE wrong_planetype.
ELSE.
mv_weight = ls_planetype-weight.
mv_tankcap = ls_planetype-tankcap.
gv_n_o_airplanes = gv_n_o_airplanes + 1.
ENDIF.
ENDMETHOD.
"constructor
METHOD display_attributes.
WRITE:
/ icon_ws_plane AS ICON,
/ 'Name of Airplane'(001) ,
/ 'Type of Airplane:'(002),
/ 'Weight:'(003),
LEFT-JUSTIFIED,
/ 'Tank capacity:'(004),
LEFT-JUSTIFIED.
ENDMETHOD.
AT c_pos_1 mv_name,
AT c_pos_1 mv_planetype,
AT c_pos_1 mv_weight
AT c_pos_1 mv_tankcap
"display_attributes
METHOD display_n_o_airplanes.
SKIP.
WRITE:
/ 'Number of airplanes:'(ca1),
104
© Copyright. All rights reserved.
Lesson: Implementing Class Constructors in Local Classes
AT c_pos_1 gv_n_o_airplanes LEFT-JUSTIFIED.
ENDMETHOD.
"display_n_o_airplanes
METHOD get_n_o_airplanes.
rv_count = gv_n_o_airplanes.
ENDMETHOD.
"get_n_o_airplanes
METHOD get_technical_attributes.
DATA: ls_planetype TYPE saplane.
READ TABLE gt_planetypes INTO ls_planetype
WITH TABLE KEY planetype = iv_type
TRANSPORTING weight tankcap.
IF sy-subrc = 0.
ev_weight = ls_planetype-weight.
ev_tankcap = ls_planetype-tankcap.
ELSE.
RAISE wrong_planetype.
ENDIF.
ENDMETHOD.
"get_technical_attributes
ENDCLASS.
"lcl_airplane IMPLEMENTATION
DATA:
go_airplane TYPE REF TO lcl_airplane,
gt_airplanes TYPE TABLE OF REF TO lcl_airplane,
gv_count
TYPE i.
START-OF-SELECTION.
*******************
lcl_airplane=>display_n_o_airplanes( ).
CREATE OBJECT go_airplane
EXPORTING
iv_name
= 'LH Berlin'
iv_planetype
= 'A321'
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
APPEND go_airplane TO gt_airplanes.
ENDIF.
CREATE OBJECT go_airplane
EXPORTING
iv_name
= 'AA New York'
iv_planetype
= '747-400'
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
APPEND go_airplane TO gt_airplanes.
ENDIF.
CREATE OBJECT go_airplane
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
APPEND go_airplane TO gt_airplanes.
ENDIF.
© Copyright. All rights reserved.
105
Unit 2: Fundamental Object-Oriented Syntax
LOOP AT gt_airplanes INTO go_airplane.
go_airplane->display_attributes( ).
ENDLOOP.
gv_count = lcl_airplane=>get_n_o_airplanes( ).
SKIP 2.
WRITE: / 'Number of airplanes'(ca1), gv_count.
106
© Copyright. All rights reserved.
Lesson: Implementing Class Constructors in Local Classes
LESSON SUMMARY
You should now be able to:
●
Create and use static constructors
© Copyright. All rights reserved.
107
Unit 2: Fundamental Object-Oriented Syntax
108
© Copyright. All rights reserved.
Unit 2
Learning Assessment
1. The CLASS statement can be nested, that is, you can define a class within a class.
Determine whether this statement is true or false.
X
True
X
False
2. Which one of the following syntax elements is used to define static attributes?
Choose the correct answer.
X
A CLASS-DATA
X
B DATA
X
C LIKE
3. Which of the following options is used to create an object?
Choose the correct answer.
X
A CREATE OBJECT ref_name
X
B APPEND ref_name
X
C CLASS ref_name
4. You must create and address objects using reference variables.
Determine whether this statement is true or false.
X
True
X
False
5. During program runtime, you create discrete objects (instances) in memory for an
existing class. This process is called instantiation.
Determine whether this statement is true or false.
X
True
X
False
© Copyright. All rights reserved.
109
Unit 2: Learning Assessment
6. When calling a static method from within the class, you can omit the class name.
Determine whether this statement is true or false.
X
True
X
False
7. In which of the following expressions can functional methods be called directly?
Choose the correct answers.
X
A IF
X
B COMPUTE
X
C MOVE
X
D WHILE
8. You can describe methods that have a _________ parameter as functional methods.
Choose the correct answer.
X
A EXPORTING
X
B CHANGING
X
C RETURNING
9. You have to define RETURNING parameters using the VALUE addition, that is they must
be pass by value.
Determine whether this statement is true or false.
X
True
X
False
10. The _____________ is a special instance method in a class.
Choose the correct answer.
110
X
A constructor
X
B function
X
C attributes
© Copyright. All rights reserved.
Unit 2: Learning Assessment
11. The instance constructor is automatically called at runtime with the CREATE OBJECT
statement.
Determine whether this statement is true or false.
X
True
X
False
12. Which of the following points are true about the static constructor?
Choose the correct answer.
X
A Each class has not more than one static constructor.
X
B The static constructor must be defined in the private area.
X
C The static constructor’s signature can have importing parameters or exceptions.
X
D The static constructor must be called explicitly from the class.
13. The instance constructor’s signature can have importing parameters or exceptions.
Determine whether this statement is true or false.
X
True
X
False
© Copyright. All rights reserved.
111
Unit 2
Learning Assessment - Answers
1. The CLASS statement can be nested, that is, you can define a class within a class.
Determine whether this statement is true or false.
X
True
X
False
2. Which one of the following syntax elements is used to define static attributes?
Choose the correct answer.
X
A CLASS-DATA
X
B DATA
X
C LIKE
3. Which of the following options is used to create an object?
Choose the correct answer.
X
A CREATE OBJECT ref_name
X
B APPEND ref_name
X
C CLASS ref_name
4. You must create and address objects using reference variables.
Determine whether this statement is true or false.
112
X
True
X
False
© Copyright. All rights reserved.
Unit 2: Learning Assessment - Answers
5. During program runtime, you create discrete objects (instances) in memory for an
existing class. This process is called instantiation.
Determine whether this statement is true or false.
X
True
X
False
6. When calling a static method from within the class, you can omit the class name.
Determine whether this statement is true or false.
X
True
X
False
7. In which of the following expressions can functional methods be called directly?
Choose the correct answers.
X
A IF
X
B COMPUTE
X
C MOVE
X
D WHILE
8. You can describe methods that have a _________ parameter as functional methods.
Choose the correct answer.
X
A EXPORTING
X
B CHANGING
X
C RETURNING
9. You have to define RETURNING parameters using the VALUE addition, that is they must
be pass by value.
Determine whether this statement is true or false.
X
True
X
False
© Copyright. All rights reserved.
113
Unit 2: Learning Assessment - Answers
10. The _____________ is a special instance method in a class.
Choose the correct answer.
X
A constructor
X
B function
X
C attributes
11. The instance constructor is automatically called at runtime with the CREATE OBJECT
statement.
Determine whether this statement is true or false.
X
True
X
False
12. Which of the following points are true about the static constructor?
Choose the correct answer.
X
A Each class has not more than one static constructor.
X
B The static constructor must be defined in the private area.
X
C The static constructor’s signature can have importing parameters or exceptions.
X
D The static constructor must be called explicitly from the class.
13. The instance constructor’s signature can have importing parameters or exceptions.
Determine whether this statement is true or false.
114
X
True
X
False
© Copyright. All rights reserved.
UNIT 3
Inheritance and Casting
Lesson 1
Implementing Inheritance
Exercise 7: Implement Inheritance
116
125
Lesson 2
Implementing Upcasts Using Inheritance
Exercise 8: Implement Upcasts
135
139
Lesson 3
Implementing Polymorphism Using Inheritance
Exercise 9: Implement Polymorphism Using Inheritance
144
149
Lesson 4
Implementing Downcasts Using Inheritance
Exercise 10: Implement Downcasts
155
159
UNIT OBJECTIVES
●
Explain generalization and specialization
●
Implement inheritance
●
Access elements of classes in inheritance
●
Implement upcasts using inheritance
●
Explain polymorphism
●
Implement polymorphism using inheritance
●
Implement downcasts using inheritance
●
Model class hierarchies
© Copyright. All rights reserved.
115
Unit 3
Lesson 1
Implementing Inheritance
LESSON OVERVIEW
This lesson explains the concept of inheritance and its implementation.
Business Example
As a developer, you need to implement inheritance for the class in your ABAP objects project.
For this reason, you require the following knowledge:
●
An understanding of inheritance
●
An understanding of Generalization and Specialization
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Explain generalization and specialization
●
Implement inheritance
●
Access elements of classes in inheritance
Generalization and Specialization
Figure 61: Example of Generalization and Specialization
116
© Copyright. All rights reserved.
Lesson: Implementing Inheritance
Specialization describes a relationship in which one class (subclass) inherits all the main
characteristics of another class (superclass). The subclass can also add new components
(attributes, methods, and so on) and replace the implementations in inherited methods. In the
latter case, the method name in the Unified Modeling Language (UML) diagram is renamed
within the subclass.
Specialization is an implementation relationship that emphasizes the similarities of the
classes. In the above example, the common components of classes LCL_CAR, LCL_TRUCK,
and LCL_BUS are defined in the UML model in the superclass, LCL_VEHICLE. The common
components of the subclasses only need to be defined and implemented in the superclass
and they are inherited by all the subclasses.
Specialization is described as an "is a" relationship semantically. For example, a truck is a
specific vehicle. Reversing the point of view is referred to as generalization.
Characteristics of Generalization and Specialization
Figure 62: Characteristics of Generalization/Specialization
Generalization and specialization provide a significantly better structure for your software
because commonly used elements only need to be stored once in a central location (in the
superclass). These elements are then automatically available to all subclasses. Changes
made at a later stage have an immediate effect on the subclasses. Therefore, do not alter the
semantics when you change a superclass.
You need knowledge of the implementation of the superclass to decide whether the inherited
components from the superclass are sufficient for the subclass or if they must be extended.
Generalization/specialization, therefore, provides strong links between the superclass and
the subclass.
When you develop additional subclasses, adapt the superclasses, too. The creation of a
subclass sometimes leads to additional requirements for the superclass. For example, when a
subclass requires certain protected components, or, when the details of implementation of
superclass are required to change because of the method implementations in subclasses.
The developer of superclass cannot predict all the requirements that subclasses need from
the superclass.
© Copyright. All rights reserved.
117
Unit 3: Inheritance and Casting
Implementation of Inheritance
Figure 63: Inheritance – Syntax
In ABAP Objects, an inheritance relationship is defined for a subclass using the INHERITING
FROM addition, followed by the superclass directly above the subclass. Usually, inheritance
hierarchies of varying complexity can be created when a superclass inherits from another
superclass, but there is no multiple inheritance in ABAP Objects, that is, only one superclass
can be specified directly above a class. However, you can use interfaces in ABAP Objects to
simulate multiple inheritance.
Inheritance must be used to implement generalization and specialization relationships. A
superclass is a generalization of its subclasses. The subclasses are in turn different
specializations of their superclasses. Thus, additions or changes are permitted in the
subclasses but you can never remove anything from a superclass in a subclass.
Inheritance is a one-sided relationship, subclasses recognize their direct superclasses but
superclasses do not recognize their subclasses. In this example, the subclass also contains
the set_type method. The subclass also defines the get_cargo method.
118
© Copyright. All rights reserved.
Lesson: Implementing Inheritance
Redefinition of Methods
Figure 64: Redefining Methods
Redefinition is when the implementation of an inherited instance method is changed for the
subclass, without changing the signature. Because the visibility section for the superclass
must remain the same, therefore, redefinition is not possible within the PRIVATE SECTION.
When you use the REDEFINITION addition, you will specify a new implementation for the
inherited method. Since the signature may not be changed, you do not need to define the
method parameters and exceptions again. Within the redefined implementation of the
method, you can use the predefined prefix “super->...” to access components in the
superclass. You may need to do this when redefining a method to call the original method of
the superclass.
© Copyright. All rights reserved.
119
Unit 3: Inheritance and Casting
Preserving Semantics During Redefinition
Figure 65: Preserving Semantics During Redefinition
In the figure Preserving Semantics During Redefinition, the two redefined methods provide
completely different information.
The semantics of the method remains the same.
Subclass Constructors
Figure 66: Definition of the Constructor in Subclasses
120
© Copyright. All rights reserved.
Lesson: Implementing Inheritance
A redefinition, as described for the methods in the figure, Definition of the Constructor in
Subclasses, would not be useful in the case of the constructor. In the subclass, either the
constructor of the superclass can be used without any changes or the subclass has been
expanded and the new parameters are now required in the constructors signature.
In ABAP Objects, the constructor is not inherited like normal methods. Any class can define
its own constructor that is fully independent from the definition of the constructor in its
superclass. A subclass can even define a constructor if there is no constructor in the
superclass.
However, when implementing the subclass constructor, it is mandatory to call the constructor
of the immediate superclass. By doing so, it is ensured that the constructor of class is always
executed, whether the created object is an instance of the class itself, or an instance of one of
its subclasses.
Because of this enforced call of the superclass constructor, the subclass constructor
generally adds parameters to the signature of the superclass constructor rather than
completely changing it.
Hint:
In this context, the concept of overloading is of relevance. With overloading, a
method can have several definitions with different signatures and different
implementations. The concept of overloading is not supported in ABAP Objects.
The usual work-around is one signature with different sets of optional
parameters.
In contrast to instance constructors, the runtime environment automatically ensures that the
static constructors of all its superclasses have already been executed before the static
constructor in a particular class is executed in the runtime system.
Rules for Calling the Constructor
Figure 67: Rules for Calling the Constructor
© Copyright. All rights reserved.
121
Unit 3: Inheritance and Casting
If a subclass has not changed its instance constructor, the constructor is adopted from the
superclass. The implementation is also inherited from the superclass.
Inheritance and Visibility
Figure 68: Inheritance and Visibility
Inheritance provides an extension of the visibility concept through protected components
(PROTECTED SECTION). The visibility of protected components lies between public and
private components. Protected components are visible to all subclasses and the class itself.
When defining local classes in ABAP Objects, follow the syntactical sequence of the PUBLIC
SECTION, the PROTECTED SECTION, and the PRIVATE SECTION.
122
© Copyright. All rights reserved.
Lesson: Implementing Inheritance
Visibility Section – Protected Versus Private
Figure 69: Protected Versus Private Section
The components inherited from the superclass may not be visible in the subclass. A subclass
can receive private components from its superclass, which cannot be address in the syntax of
the subclass. Private components of superclasses can only be addressed indirectly using
public or protected methods from the superclass, which in turn, can access the private
attributes. These restrictions are necessary to ensure that centralized maintenance is
possible.
In this example, it is possible to access the protected constant C_POS_1 in superclass
LCL_VEHICLE directly from its subclass LCL_BUS. On the other hand, the only way to access
the private MV_MAKE and MV_MODEL attributes from the subclasses of LCL_VEHICLE is to
call methods of LCL_VEHICLE. These methods have to be public or protected.
Using the PRIVATE SECTION, you can change superclasses without the need to know the
subclasses. As long as the changes you make do not affect the semantics, you do not need to
adapt the subclasses. This is because they only indirectly access the private components
from the superclass.
Inheritance and Static Components
The following is a summary of static components and inheritance:
●
A class that defines a public or protected static attribute shares this attribute with all its
subclasses.
●
Static methods cannot be redefined.
●
The static constructor of a superclass is executed when the superclass or one of its
subclasses is accessed for the first time.
●
A subclass can always have a static constructor, irrespective of the superclass.
© Copyright. All rights reserved.
123
Unit 3: Inheritance and Casting
●
124
If a subclass and its superclass both have a static constructor, then both constructors are
executed when we access the subclass for the first time. If access to the superclass and
subclass static constructor occurs at the same time, the superclass static constructor will
execute first, immediately followed by the subclass static constructor.
© Copyright. All rights reserved.
Unit 3
Exercise 7
Implement Inheritance
Business Example
You must refine your airplane management program. Create classes for specific airplanes in
relation to a general airplane class.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S5.
Solution: SAPBC401_INH_S1
.
Define a Specialized Passenger Plane Class
Define the local class LCL_PASSENGER_PLANE for passenger planes. Define the class as a
subclass of LCL_AIRPLANE. Add specific attributes and methods and redefine the
DISPLAY_ATTRIBUTES method.
1. Define a new local class LCL_PASSENGER_PLANE and make it a subclass of the already
existing LCL_AIRPLANE.
2. Is there a specific sequence in which you have to define the classes in the source code?
3. The class must have a private instance attribute, MV_SEATS, with the same type as the
table field SAPLANE-SEATSMAX.
4. Define and implement an instance constructor that assigns values to all instance
attributes in the class.
5. Redefine method DISPLAY_ATTRIBUTES so that all instance attributes are displayed
using the WRITE statement.
Make sure that the output of specific attributes are aligned with the output from the
superclass. Therefore, change the visibility of the C_POS_1 constant so that you can use it
in your subclass.
Define a Specialized Cargo Plane Class
In the class LCL_AIRPLANE, define the local subclass LCL_CARGO_PLANE for cargo planes.
1. The class must have a private instance attribute, MV_CARGO , with the same type as the
table field SCPLANE-CARGOMAX.
© Copyright. All rights reserved.
125
Unit 3: Inheritance and Casting
2. Define and implement an instance constructor that assigns values to all instance
attributes in the class.
3. Redefine DISPLAY_ATTRIBUTES so that all instance attributes are displayed using the
WRITE statement.
Instantiate the New Classes
Create instances of your new classes and display their attributes.
1. In the main program, define a suitably typed reference variable for each of your new
classes.
2. Before instantiating any objects, call the static method DISPLAY_N_O_AIRPLANES.
3. Use the two references to create an instance of each of the subclasses
LCL_PASSENGER_PLANE and LCL_CARGO_PLANE. Decide for yourself how to fill the
attributes.
4. Call the DISPLAY_ATTRIBUTES method for both instances.
5. Save, check, and activate your program.
Analyze Your Program With the Debugger
Debug your program.
1. Could the method GET_TECHNICAL_ATTRIBUTES be called directly from the redefined
method DISPLAY_ATTRIBUTES of the subclasses?
2. Observe the program flow in the ABAP Debugger, paying special attention to the call of the
DISPLAY_ATTRIBUTES method.
126
© Copyright. All rights reserved.
Unit 3
Solution 7
Implement Inheritance
Business Example
You must refine your airplane management program. Create classes for specific airplanes in
relation to a general airplane class.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_BAS_S5.
Solution: SAPBC401_INH_S1
.
Define a Specialized Passenger Plane Class
Define the local class LCL_PASSENGER_PLANE for passenger planes. Define the class as a
subclass of LCL_AIRPLANE. Add specific attributes and methods and redefine the
DISPLAY_ATTRIBUTES method.
1. Define a new local class LCL_PASSENGER_PLANE and make it a subclass of the already
existing LCL_AIRPLANE.
a) See the source code extract from the model solution.
2. Is there a specific sequence in which you have to define the classes in the source code?
A superclass has to be defined first. Otherwise, the syntax check will not know it when you
refer to superclass in the INHERITING FROM part of the subclass definition.
3. The class must have a private instance attribute, MV_SEATS, with the same type as the
table field SAPLANE-SEATSMAX.
a) See the source code extract from the model solution.
4. Define and implement an instance constructor that assigns values to all instance
attributes in the class.
a) See the source code extract from the model solution.
5. Redefine method DISPLAY_ATTRIBUTES so that all instance attributes are displayed
using the WRITE statement.
Make sure that the output of specific attributes are aligned with the output from the
superclass. Therefore, change the visibility of the C_POS_1 constant so that you can use it
in your subclass.
a) See the source code extract from the model solution.
© Copyright. All rights reserved.
127
Unit 3: Inheritance and Casting
Define a Specialized Cargo Plane Class
In the class LCL_AIRPLANE, define the local subclass LCL_CARGO_PLANE for cargo planes.
1. The class must have a private instance attribute, MV_CARGO , with the same type as the
table field SCPLANE-CARGOMAX.
a) See the source code extract from the model solution.
2. Define and implement an instance constructor that assigns values to all instance
attributes in the class.
a) See the source code extract from the model solution.
3. Redefine DISPLAY_ATTRIBUTES so that all instance attributes are displayed using the
WRITE statement.
a) See the source code extract from the model solution.
Instantiate the New Classes
Create instances of your new classes and display their attributes.
1. In the main program, define a suitably typed reference variable for each of your new
classes.
a) See the source code extract from the model solution.
2. Before instantiating any objects, call the static method DISPLAY_N_O_AIRPLANES.
a) See the source code extract from the model solution.
3. Use the two references to create an instance of each of the subclasses
LCL_PASSENGER_PLANE and LCL_CARGO_PLANE. Decide for yourself how to fill the
attributes.
a) See the source code extract from the model solution.
4. Call the DISPLAY_ATTRIBUTES method for both instances.
a) See the source code extract from the model solution.
5. Save, check, and activate your program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
Analyze Your Program With the Debugger
Debug your program.
1. Could the method GET_TECHNICAL_ATTRIBUTES be called directly from the redefined
method DISPLAY_ATTRIBUTES of the subclasses?
No, because the method is private in the superclass.
2. Observe the program flow in the ABAP Debugger, paying special attention to the call of the
DISPLAY_ATTRIBUTES method.
a) To start the ABAP Debugger, choose Program → Execute → Debugging.
128
© Copyright. All rights reserved.
Lesson: Implementing Inheritance
b) To debug your program, on the application toolbar, choose the Execute button, or
press F8.
Solution: SAPBC401_INH_S1
REPORT
sapbc401_inh_s1.
TYPE-POOLS icon.
*------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*------------------------------------------------*
CLASS lcl_airplane DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
EXCEPTIONS
wrong_planetype,
display_attributes.
CLASS-METHODS:
class_constructor,
display_n_o_airplanes,
get_n_o_airplanes
RETURNING value(rv_count) TYPE i.
PROTECTED SECTION.
CONSTANTS:
c_pos_1 TYPE i VALUE 30.
PRIVATE SECTION.
TYPES:
ty_planetypes TYPE STANDARD TABLE OF saplane
WITH NON-UNIQUE KEY planetype.
DATA:
mv_name
mv_planetype
mv_weight
mv_tankcap
TYPE
TYPE
TYPE
TYPE
string,
saplane-planetype,
saplane-weight,
saplane-tankcap.
CLASS-DATA:
gv_n_o_airplanes TYPE i,
gt_planetypes
TYPE ty_planetypes.
CLASS-METHODS:
get_technical_attributes
IMPORTING
iv_type
TYPE saplane-planetype
EXPORTING
ev_weight
TYPE saplane-weight
ev_tankcap TYPE saplane-tankcap
EXCEPTIONS
wrong_planetype.
© Copyright. All rights reserved.
129
Unit 3: Inheritance and Casting
ENDCLASS.
"lcl_airplane DEFINITION
*-------------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
METHOD class_constructor.
SELECT * FROM saplane INTO TABLE gt_planetypes.
ENDMETHOD.
"class_constructor
METHOD constructor.
mv_name
= iv_name.
mv_planetype = iv_planetype.
get_technical_attributes(
EXPORTING
iv_type = iv_planetype
IMPORTING
ev_weight = mv_weight
ev_tankcap = mv_tankcap
EXCEPTIONS
wrong_planetype = 1 ).
IF sy-subrc <> 0.
RAISE wrong_planetype.
ELSE.
gv_n_o_airplanes = gv_n_o_airplanes + 1.
ENDIF.
ENDMETHOD.
"constructor
METHOD display_attributes.
WRITE:
/ icon_ws_plane AS ICON,
/ 'Name of Airplane'(001) ,
/ 'Type of Airplane:'(002),
/ 'Weight:'(003),
LEFT-JUSTIFIED,
/ 'Tank capacity:'(004),
LEFT-JUSTIFIED.
ENDMETHOD.
AT c_pos_1 mv_name,
AT c_pos_1 mv_planetype,
AT c_pos_1 mv_weight
AT c_pos_1 mv_tankcap
"display_attributes
METHOD display_n_o_airplanes.
SKIP.
WRITE:
/ 'Number of airplanes:'(ca1),
AT c_pos_1 gv_n_o_airplanes LEFT-JUSTIFIED.
ENDMETHOD.
"display_n_o_airplanes
METHOD get_n_o_airplanes.
rv_count = gv_n_o_airplanes.
ENDMETHOD.
"get_n_o_airplanes
METHOD get_technical_attributes.
DATA: ls_planetype TYPE saplane.
READ TABLE gt_planetypes INTO ls_planetype
WITH TABLE KEY planetype = iv_type
TRANSPORTING weight tankcap.
130
© Copyright. All rights reserved.
Lesson: Implementing Inheritance
IF sy-subrc = 0.
ev_weight = ls_planetype-weight.
ev_tankcap = ls_planetype-tankcap.
ELSE.
RAISE wrong_planetype.
ENDIF.
ENDMETHOD.
"get_technical_attributes
ENDCLASS.
"lcl_airplane IMPLEMENTATION
*------------------------------------------------*
*
CLASS lcl_cargo_plane DEFINITION
*------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING FROM lcl_airplane.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
iv_cargo
TYPE s_plan_car
EXCEPTIONS
wrong_planetype,
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:
mv_cargo TYPE s_plan_car.
ENDCLASS.
"lcl_cargo_plane DEFINITION
*------------------------------------------------*
*
CLASS lcl_cargo_plane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
METHOD constructor.
super->constructor(
EXPORTING
iv_name
= iv_name
iv_planetype = iv_planetype
EXCEPTIONS
wrong_planetype = 1 ).
IF sy-subrc <> 0.
RAISE wrong_planetype.
ENDIF.
mv_cargo = iv_cargo.
ENDMETHOD.
"constructor
METHOD display_attributes.
super->display_attributes( ).
WRITE:
/ 'Max Cargo:'(005), AT c_pos_1 mv_cargo
LEFT-JUSTIFIED.
ULINE.
© Copyright. All rights reserved.
131
Unit 3: Inheritance and Casting
ENDMETHOD.
ENDCLASS.
"display_attributes
"lcl_cargo_plane IMPLEMENTATION
*------------------------------------------------*
*
CLASS lcl_passenger_plane DEFINITION
*------------------------------------------------*
CLASS lcl_passenger_plane
DEFINITION INHERITING FROM lcl_airplane.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
iv_seats
TYPE s_seatsmax
EXCEPTIONS
wrong_planetype,
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:
mv_seats TYPE s_seatsmax.
ENDCLASS.
"lcl_passenger_plane DEFINITION
*------------------------------------------------*
*
CLASS lcl_passenger_plane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
METHOD constructor.
super->constructor(
EXPORTING
iv_name
= iv_name
iv_planetype = iv_planetype
EXCEPTIONS
wrong_planetype = 1 ).
IF sy-subrc <> 0.
RAISE wrong_planetype.
ENDIF.
mv_seats = iv_seats.
ENDMETHOD.
"constructor
METHOD display_attributes.
super->display_attributes( ).
WRITE:
/ 'Max Seats:'(006), AT c_pos_1 mv_seats
LEFT-JUSTIFIED.
ULINE.
ENDMETHOD.
"display_attributes
ENDCLASS.
"lcl_passenger_plane IMPLEMENTATION
DATA:
go_airplane
go_cargo
go_passenger
gt_airplanes
132
TYPE
TYPE
TYPE
TYPE
REF TO lcl_airplane,
REF TO lcl_cargo_plane,
REF TO lcl_passenger_plane,
TABLE OF REF TO lcl_airplane,
© Copyright. All rights reserved.
Lesson: Implementing Inheritance
gv_count
TYPE i.
START-OF-SELECTION.
*******************
lcl_airplane=>display_n_o_airplanes( ).
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
* do nothing for now
ENDIF.
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
* do nothing just now
ENDIF.
go_passenger->display_attributes( ).
go_cargo->display_attributes( ).
gv_count = lcl_airplane=>get_n_o_airplanes( ).
SKIP 2.
WRITE: / 'Number of airplanes'(ca1), gv_count.
© Copyright. All rights reserved.
133
Unit 3: Inheritance and Casting
LESSON SUMMARY
You should now be able to:
134
●
Explain generalization and specialization
●
Implement inheritance
●
Access elements of classes in inheritance
© Copyright. All rights reserved.
Unit 3
Lesson 2
Implementing Upcasts Using Inheritance
LESSON OVERVIEW
This lesson explains the concept of up-casts and the dynamic and the static type of reference
variable. This lesson also explains the method of implementing up-casts.
Business Example
As a developer, you need to implement the upcast concept for your ABAP object classes. For
this reason, you require the following knowledge:
●
An understanding of inheritance
●
An understanding of upcasts
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement upcasts using inheritance
Upcasts
Figure 70: Upcast (Widening Cast) with Object References
If you assign a subclass reference to a superclass reference, this subclass ensures that all
components that you can access syntactically after the cast assignment are actually available
in the instance. The subclass always contains at least the same components as the
superclass always the name and the signature of redefined methods are identical.
© Copyright. All rights reserved.
135
Unit 3: Inheritance and Casting
The user can address only those methods and attributes from the subclass instance that they
can from the superclass instance.
Hint:
Note that with redefined methods, the implementation of the subclass is
executed using the superclass static type of reference.
In this example, after the assignment, you can only access the methods GET_MAKE,
GET_COUNT, DISPLAY_ATTRIBUTES, SET_ATTRIBUTES, and ESTIMATE_FUEL of the
instance LCL_TRUCK by using the reference GO_VEHICLE.
If there are any restrictions regarding visibility, they are left unchanged. It is not possible to
access the specific components from the class LCL_TRUCK of the instance GET_CARGO in
the example using the reference GO_VEHICLE. The view or possible access to methods is
either narrowed or left unchanged. There is a switch from a view of several components to a
view of a few components. As the target variable can accept more dynamic types in
comparison to the source variable, this assignment is also called widening cast.
Static and Dynamic Type
Figure 71: Static and Dynamic Types of References
Types of a reference variable at runtime in object oriented programming:
●
Static
●
Dynamic
In the example, LCL_VEHICLE is the static type of the variable GO_VEHICLE. Depending on
the cast assignment, the dynamic type is either LCL_BUS or LCL_TRUCK. In the ABAP
Debugger, the dynamic type is specified in the following form:
object_id<\PROGRAM=program_name\CLASS=dynamic_type>
136
© Copyright. All rights reserved.
Lesson: Implementing Upcasts Using Inheritance
Note:
Assignments between reference variables are possible whenever the static type of
the target variables is more general or equal to the dynamic type of the source
variables.
© Copyright. All rights reserved.
137
Unit 3: Inheritance and Casting
138
© Copyright. All rights reserved.
Unit 3
Exercise 8
Implement Upcasts
Business Example
As a developer, your airplane management program should display the attributes of the
airplane objects generically, that is, it should be open to future extensions with additional
airplane classes.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_INH_S1
.
Solution: SAPBC401_INH_S2
.
Buffer References in an Internal Table
Buffer the airplane references in a suitable type of internal table.
1. Complete your program ZBC401_##_MAIN or copy the sample solution program from the
previous exercise.
2. In your main program, define an internal table for buffering airplane references if you do
not already have one. The row type of the internal table should be REF TO LCL_AIRPLANE.
Display the Attributes of All Airplane Types Created
Display the attributes of all airplane types that were created so far.
1. Insert the references to your passenger and cargo airplanes into the internal table.
2. Program a loop through the contents of the internal table. Call the DISPLAY_ATTRIBUTES
method every time the loop runs.
Analyze the Program
1. What would happen if the method DISPLAY_ATTRIBUTES had not been redefined in the
subclasses?
2. Follow the program flow in the ABAP Debugger, paying special attention to the call of the
method DISPLAY_ATTRIBUTES.
© Copyright. All rights reserved.
139
Unit 3
Solution 8
Implement Upcasts
Business Example
As a developer, your airplane management program should display the attributes of the
airplane objects generically, that is, it should be open to future extensions with additional
airplane classes.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_INH_S1
.
Solution: SAPBC401_INH_S2
.
Buffer References in an Internal Table
Buffer the airplane references in a suitable type of internal table.
1. Complete your program ZBC401_##_MAIN or copy the sample solution program from the
previous exercise.
a) Carry out this step as usual. Additional information is available in the SAP Library.
2. In your main program, define an internal table for buffering airplane references if you do
not already have one. The row type of the internal table should be REF TO LCL_AIRPLANE.
a) See the source code extract from the model solution.
Display the Attributes of All Airplane Types Created
Display the attributes of all airplane types that were created so far.
1. Insert the references to your passenger and cargo airplanes into the internal table.
a) See the source code extract from the model solution.
2. Program a loop through the contents of the internal table. Call the DISPLAY_ATTRIBUTES
method every time the loop runs.
a) See the source code extract from the model solution.
Analyze the Program
1. What would happen if the method DISPLAY_ATTRIBUTES had not been redefined in the
subclasses?
The implementation from the superclass would be executed. Your program would not
contain polymorphism.
2. Follow the program flow in the ABAP Debugger, paying special attention to the call of the
method DISPLAY_ATTRIBUTES.
a) Carry out this step as usual. Additional information is available in the SAP Library.
140
© Copyright. All rights reserved.
Lesson: Implementing Upcasts Using Inheritance
Solution: SAPBC401_INH_S2
REPORT sapbc401_inh_s2.
TYPE-POOLS icon.
*-----------------------------------------------*
* CLASS lcl_airplane DEFINITION
*-----------------------------------------------*
CLASS lcl_airplane DEFINITION.
...
ENDCLASS. "lcl_airplane DEFINITION
*-----------------------------------------------*
* CLASS lcl_airplane IMPLEMENTATION
*-----------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
...
ENDCLASS. "lcl_airplane IMPLEMENTATION
*-----------------------------------------------*
* CLASS lcl_cargo_plane DEFINITION
*-----------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING
FROM lcl_airplane.
...
ENDCLASS. "lcl_cargo_plane DEFINITION
*-----------------------------------------------*
*CLASS lcl_cargo_plane IMPLEMENTATION
*-----------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
...
ENDCLASS. "lcl_cargo_plane IMPLEMENTATION
*-----------------------------------------------*
* CLASS lcl_passenger_plane DEFINITION
*-----------------------------------------------*
CLASS lcl_passenger_plane
DEFINITION INHERITING FROM lcl_airplane.
...
ENDCLASS. "lcl_passenger_plane DEFINITION
*-----------------------------------------------*
* CLASS lcl_passenger_plane IMPLEMENTATION
*-----------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
...
ENDCLASS.
"lcl_passenger_plane IMPLEMENTATION
DATA:
go_airplane TYPE REF TO lcl_airplane,
go_cargo TYPE REF TO lcl_cargo_plane,
go_passenger TYPE REF TO lcl_passenger_plane,
gt_airplanes TYPE TABLE OF REF TO lcl_airplane,
gv_count TYPE i.
START-OF-SELECTION.
*******************
lcl_airplane=>display_n_o_airplanes( ).
© Copyright. All rights reserved.
141
Unit 3: Inheritance and Casting
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
APPEND go_passenger TO gt_airplanes.
ENDIF.
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
APPEND go_cargo TO gt_airplanes.
ENDIF.
LOOP AT gt_airplanes INTO go_airplane.
go_airplane->display_attributes( ).
ENDLOOP.
gv_count = lcl_airplane=>get_n_o_airplanes( ).
SKIP 2.
WRITE: / 'Number of airplanes'(ca1), gv_count.
142
© Copyright. All rights reserved.
Lesson: Implementing Upcasts Using Inheritance
LESSON SUMMARY
You should now be able to:
●
Implement upcasts using inheritance
© Copyright. All rights reserved.
143
Unit 3
Lesson 3
Implementing Polymorphism Using Inheritance
LESSON OVERVIEW
This lesson explains polymorphism and implementing polymorphism using inheritance.
Business Example
As a developer, you need to implement polymorphism using inheritance. For this reason, you
require the following knowledge:
●
An understanding of polymorphism
●
An understanding of generic access and upcast assignments
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Explain polymorphism
●
Implement polymorphism using inheritance
Generic Access to Objects
Figure 72: Generic Access After Up-Cast Assignments
144
© Copyright. All rights reserved.
Lesson: Implementing Polymorphism Using Inheritance
A typical use for up-cast assignments is to prepare for generic access. A user who is not
interested in the finer points of the instances of the subclasses but simply needs to address
the shared components can use a superclass reference for this access.
In the example, a travel agency LCL_RENTAL needs to manage all imaginable kinds of
vehicles in one list. To manage all these vehicles in one list, create an internal table and assign
it with an appropriate type for the references to the vehicle instances. The car rental company
also needs to be able to calculate the required amount of fuel for all its vehicles. In this case,
the DISPLAY_ATTRIBUTES method,which is defined in the superclass LCL_VEHICLE must
be redefined in all subclasses.
Row Type of the Internal Table in the Application – Example
Figure 73: Row Type of the Internal Table in the Application – Example
When objects of different classes (LCL_BUS, LCL_TRUCK and LCL_CAR) are specified as
type superclass references (LCL_VEHICLE), these objects can be stored in an internal table.
The shared components of the subclass objects can then be accessed uniformly. For this
example, you need the method ADD_VEHICLE to copy the references to the vehicle types into
the internal table. The import parameter of this method is already typed as the reference to
the superclass.
© Copyright. All rights reserved.
145
Unit 3: Inheritance and Casting
Up-Cast and Generic Access in the Application – Example
Figure 74: Up-Cast and Generic Access in the Application – Example
In this example, the up-cast assignment occurs when the vehicle reference is transferred to
the formal parameter of ADD_VEHICLE method. The shared component is generically
accessed within the loop around the internal table containing all of the vehicle references. The
DISPLAY_ATTRIBUTES method was inherited from the LCL_VEHICLE superclass and may
have been redefined.
146
© Copyright. All rights reserved.
Lesson: Implementing Polymorphism Using Inheritance
Polymorphism
Figure 75: Polymorphism – Generic Access Using the Superclass Reference
The implementation to be executed when DISPLAY_ATTRIBUTES is called depends on which
object the superclass reference LO_VEHICLE refers to. The dynamic type (not the static type)
of the reference variable is used to search for the implementation of a method. Therefore,
when lo_vehicle->display_attributes is called, the implementation is not executed from
LCL_VEHICLE (static type of LO_VEHICLE) because the method was redefined in all vehicle
classes.
When an instance receives a message to execute a particular method, the method that
implemented the class of this instance is executed. If the class has not been redefined in the
method, the implementation from the superclass is executed.
Characteristics of Polymorphism
When objects from different classes react differently to the same method calls, this is known
as polymorphism. The possibility of polymorphism is one of the main strengths of inheritance.
A client can handle different classes uniformly, irrespective of their implementation. The
runtime system searches for the right implementation of a method on behalf of the client.
Polymorphism can be used to write programs that are highly generic, that is, they do not need
to be changed significantly if use cases are added. For instance, polymorphism may make it
easy to add motorbikes to this example. You simply need to define a new subclass of
LCL_VEHICLE, which you can call LCL_MOTORBIKE. You would also have to redefine the
inherited method DISPLAY_ATTRIBUTES. Without needing any more changes, your vehicle
management system can then work with motorbikes, as well as, calculate the required fuel
levels for them.
© Copyright. All rights reserved.
147
Unit 3: Inheritance and Casting
Generic Calls in the Procedural Programming Model
Figure 76: Generic Calls in the Procedural Programming Model
Using dynamic function module calls, you can program generically in ABAP, even without an
object-oriented programming model. When you compare dynamic function module call
with polymorphism through inheritance, the source code is less self-explanatory and is more
susceptible to errors in dynamic function module call. For example, the syntax check can only
check whether the function module is called correctly or not. The syntax check cannot check
whether the internal table contains a valid function module name for each vehicle or not.
148
© Copyright. All rights reserved.
Unit 3
Exercise 9
Implement Polymorphism Using Inheritance
Business Example
You need to encapsulate the management of airplane instances in a new class instead of the
main program.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_INH_T3.
Solution: SAPBC401_INH_S3
.
Define a Local Class
Define a local class for airlines.
1. Complete your program ZBC401_##_MAIN or copy the template program. If you copy the
template program, you can go directly to the next step. Otherwise, copy the local class
LCL_CARRIER. along with the definition and implementation of the class. from the
template program and paste it into your own program.
2. Define a private instance attribute MT_AIRPLANES to storereferences to airplanes.
3. Define and implement a public method ADD_AIRPLANE so that airplane references can be
added to the previously defined list MT_AIRPLANES. The method should have one import
parameter that is IO_PLANE.
4. Define and implement a private instance method DISPLAY_AIRPLANES. In this method,
loop at the list of airplanes and call method DISPLAY_ATTRIBUTES for each airplane.
5. Extend the implementation of the method DISPLAY_ATTRIBUTES in a way that not
only the information about the carrier itself is displayed, but also all its airplanes. Use the
previously defined method DISPLAY_AIRPLANES.
Create an Instance and Transfer References to the Instance
In the main program, create an airline instance. Transfer some airplane references to the
airline instance and display the attributes.
1. Remove all of the statements from the main program that define the global internal table
for airplane references and their insertions.
2. In the main program, define a suitably typed reference variable for your new airline class.
3. Using the reference, generate an instance of your class LCL_CARRIER. Decide for yourself
how to fill the attributes.
4. Call the method ADD_AIRPLANE to transfer each airplane instance to the carrier. You may
also create and transfer additional airplanes.
5. Display the attributes of the airline by calling its method DISPLAY_ATTRIBUTES.
© Copyright. All rights reserved.
149
Unit 3
Solution 9
Implement Polymorphism Using Inheritance
Business Example
You need to encapsulate the management of airplane instances in a new class instead of the
main program.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_INH_T3.
Solution: SAPBC401_INH_S3
.
Define a Local Class
Define a local class for airlines.
1. Complete your program ZBC401_##_MAIN or copy the template program. If you copy the
template program, you can go directly to the next step. Otherwise, copy the local class
LCL_CARRIER. along with the definition and implementation of the class. from the
template program and paste it into your own program.
a) Carry out this step in the usual manner. Additional information is available in the SAP
Library.
b) Refer the source code extract from the model solution.
2. Define a private instance attribute MT_AIRPLANES to storereferences to airplanes.
a) Refer the source code extract from the model solution.
3. Define and implement a public method ADD_AIRPLANE so that airplane references can be
added to the previously defined list MT_AIRPLANES. The method should have one import
parameter that is IO_PLANE.
a) Refer the source code extract from the model solution.
4. Define and implement a private instance method DISPLAY_AIRPLANES. In this method,
loop at the list of airplanes and call method DISPLAY_ATTRIBUTES for each airplane.
a) Refer the source code extract from the model solution.
5. Extend the implementation of the method DISPLAY_ATTRIBUTES in a way that not
only the information about the carrier itself is displayed, but also all its airplanes. Use the
previously defined method DISPLAY_AIRPLANES.
a) Refer the source code extract from the model solution.
Create an Instance and Transfer References to the Instance
In the main program, create an airline instance. Transfer some airplane references to the
airline instance and display the attributes.
1. Remove all of the statements from the main program that define the global internal table
for airplane references and their insertions.
a) Refer the source code extract from the model solution.
150
© Copyright. All rights reserved.
Lesson: Implementing Polymorphism Using Inheritance
2. In the main program, define a suitably typed reference variable for your new airline class.
a) Refer the source code extract from the model solution.
3. Using the reference, generate an instance of your class LCL_CARRIER. Decide for yourself
how to fill the attributes.
a) Refer the source code extract from the model solution.
4. Call the method ADD_AIRPLANE to transfer each airplane instance to the carrier. You may
also create and transfer additional airplanes.
a) Refer the source code extract from the model solution.
5. Display the attributes of the airline by calling its method DISPLAY_ATTRIBUTES.
a) Refer the source code extract from the model solution.
SAPBC401_INH_S3
REPORT sapbc401_inh_s3.
TYPE-POOLS icon.
*------------------------------------------------*
* CLASS lcl_airplane DEFINITION
*------------------------------------------------*
CLASS lcl_airplane DEFINITION.
...
ENDCLASS. "lcl_airplane DEFINITION
*------------------------------------------------*
* CLASS lcl_airplane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
...
ENDCLASS. "lcl_airplane IMPLEMENTATION
*------------------------------------------------*
* CLASS lcl_cargo_plane DEFINITION
*------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING
FROM lcl_airplane.
...
ENDCLASS. "lcl_cargo_plane DEFINITION
*------------------------------------------------*
* CLASS lcl_cargo_plane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
...
ENDCLASS. "lcl_cargo_plane IMPLEMENTATION
*------------------------------------------------*
* CLASS lcl_passenger_plane DEFINITION
*------------------------------------------------*
CLASS lcl_passenger_plane DEFINITION INHERITING
FROM lcl_airplane.
...
ENDCLASS. "lcl_passenger_plane DEFINITION
*------------------------------------------------*
* CLASS lcl_passenger_plane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
© Copyright. All rights reserved.
151
Unit 3: Inheritance and Casting
...
ENDCLASS. "lcl_passenger_plane IMPLEMENTATION
*------------------------------------------------*
* CLASS lcl_carrier DEFINITION
*------------------------------------------------*
CLASS lcl_carrier DEFINITION.
PUBLIC SECTION.
METHODS:
constructor IMPORTING iv_name TYPE string,
display_attributes,
add_airplane IMPORTING io_plane TYPE REF TO lcl_airplane.
PRIVATE SECTION.
DATA:
mv_name TYPE string,
mt_airplanes TYPE TABLE OF REF TO lcl_airplane.
METHODS:
display_airplanes.
ENDCLASS. "lcl_carrier DEFINITION
*------------------------------------------------*
* CLASS lcl_carrier IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
ENDMETHOD. "constructor
METHOD display_attributes.
SKIP 2.
WRITE: icon_flight AS ICON, mv_name.
ULINE.
ULINE.
me->display_airplanes( ).
ENDMETHOD. "display_attributes
METHOD add_airplane.
APPEND io_plane TO mt_airplanes.
ENDMETHOD. "add_airplane
METHOD display_airplanes.
DATA: lo_plane TYPE REF TO lcl_airplane.
LOOP AT mt_airplanes INTO lo_plane.
lo_plane->display_attributes( ).
ENDLOOP.
ENDMETHOD. "display_airplanes
ENDCLASS. "lcl_carrier IMPLEMENTATION
DATA:
go_carrier TYPE REF TO lcl_carrier,
go_airplane TYPE REF TO lcl_airplane,
go_cargo TYPE REF TO lcl_cargo_plane,
go_passenger TYPE REF TO lcl_passenger_plane,
gv_count TYPE i.
152
© Copyright. All rights reserved.
Lesson: Implementing Polymorphism Using Inheritance
START-OF-SELECTION.
*******************
***** Create Carrier
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly-Travel'.
***** Passenger Plane
CREATE OBJECT go_passenger
EXPORTING
iv_name = 'LH BERLIN'
iv_planetype = '747-400'
iv_seats = 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
go_carrier->add_airplane( go_passenger ).
ENDIF.
***** cargo Plane
CREATE OBJECT go_cargo
EXPORTING
iv_name = 'US Hercules'
iv_planetype = '747-200F'
iv_cargo = 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
go_carrier->add_airplane( go_cargo ).
ENDIF.
***** output carrier (including list of airplanes)
go_carrier->display_attributes( ).
© Copyright. All rights reserved.
153
Unit 3: Inheritance and Casting
LESSON SUMMARY
You should now be able to:
154
●
Explain polymorphism
●
Implement polymorphism using inheritance
© Copyright. All rights reserved.
Unit 3
Lesson 4
Implementing Downcasts Using Inheritance
LESSON OVERVIEW
This lesson explains the concept of downcast assignments (narrowing cast).
Business Example
As a developer, you need to create a subclass from the airplane class and then use casting to
access different attributes. For this reason, you require the following knowledge:
●
An understanding of downcasts
●
An understanding of inheritance
●
An understanding of implementing downcasts using Inheritance
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement downcasts using inheritance
●
Model class hierarchies
Downcasts
Figure 77: Downcast (Narrowing Cast) with Object References
Reference variables of the superclass can also refer to the subclass instances at runtime. You
may copy this reference back to a reference variable of the subclass type.
© Copyright. All rights reserved.
155
Unit 3: Inheritance and Casting
To assign a superclass reference to a subclass reference, you must use the downcast
assignment operator MOVE ... ?TO ... or its short form ?=. Otherwise, you get a
message stating that it is not certain that all the components that can be accessed
syntactically after the cast assignment are actually available in the instance. As a rule, the
subclass contains more components than the superclass.
After assigning this type of reference back to a subclass reference to the implementing class,
clients are no longer limited to inherited components. In the example shown in the figure,
Downcast (Narrowing-Cast) with Object References, all the components of the LCL_TRUCK
instance can be accessed again after the assignment using the GO_TRUCK2 reference.
Therefore, usually the view is either widened or not changed. This type of assignment of
reference variables is known as down-cast. There is a switch from a view of a few components
to a view of many components. As the target variable can accept less dynamic types after the
assignment, this assignment is also called narrowing cast.
Specific Access After Downcast Assignments
Figure 78: Specific Access After Downcast Assignments
Downcast assignments are used when you need to address specific components of instances
and keep the references of these components in variables that are typed on the superclass. A
user who is interested in the finer points of the instances of a subclass cannot use the
superclass reference for this access because it allows access only to the shared components.
156
© Copyright. All rights reserved.
Lesson: Implementing Downcasts Using Inheritance
Exceptions Handling for Downcasts
Figure 79: Down-Cast and Exception Handling in the Application - Example
In this example, a car rental company (LCL_RENTAL) has to determine the maximum
capacity of its trucks, but it stores all types of vehicle references in an internal table
LCL_VEHICLE. There may be a problem if there is no truck reference in the LO_VEHICLE
superclass reference at runtime but the downcast assignment operator tries to copy the
reference to the now invalid reference LO_TRUCK.
In contrast to the up-cast assignment, it is possible that the static type of the target variable
(LO_TRUCK) is no more general than nor is the same as the dynamic type of the source
variable (LO_VEHICLE), namely when LO_VEHICLE contains bus or sports car references.
That is the reason why with this kind of cast, the runtime system checks before the
assignment whether the current content of the source variable corresponds to the type
requirements of the target variable. Otherwise, an exception that can be handled is triggered
and the original value of the target variable remains the same.
You can identify this exception of the error class CX_SY_MOVE_CAST_ERROR using the TRYENDTRY and the CATCH statement. Another way of preventing this runtime error is to use
runtime type identification (RTTI) classes. You can use RTTI classes to determine the
dynamic type at runtime and set a condition for the cast.
© Copyright. All rights reserved.
157
Unit 3: Inheritance and Casting
158
© Copyright. All rights reserved.
Unit 3
Exercise 10
Implement Downcasts
Business Example
As a developer, design an application where you want to determine the highest cargo load of
all the cargo planes, without knowing the details.
Template: SAPBC401_INH_S3
.
Solution: SAPBC401_INH_S3_OPT
.
Determine the highest cargo value.
1. In the LCL_CARGO_PLANE class, define and implement the GET_CARGO public functional
method to return the cargo value. Define a returning parameter RV_CARGO.
2. In the LCL_CARRIER class, define and implement the GET_MAX_CARGO private function
method to calculate the highest cargo value (load capacity) of all cargo planes. Loop at the
list of airplanes and use the downcast technique to identify cargo planes. For those
airplanes for which the downcast was successful, you can then call the GET_CARGO
method defined and implemented in the previous step.
3. Call the GET_MAX_CARGO method from within the DISPLAY_ATTRIBUTES method class
LCL_CARRIER and output the result.
© Copyright. All rights reserved.
159
Unit 3
Solution 10
Implement Downcasts
Business Example
As a developer, design an application where you want to determine the highest cargo load of
all the cargo planes, without knowing the details.
Template: SAPBC401_INH_S3
.
Solution: SAPBC401_INH_S3_OPT
.
Determine the highest cargo value.
1. In the LCL_CARGO_PLANE class, define and implement the GET_CARGO public functional
method to return the cargo value. Define a returning parameter RV_CARGO.
a) See the source code extract from the model solution.
2. In the LCL_CARRIER class, define and implement the GET_MAX_CARGO private function
method to calculate the highest cargo value (load capacity) of all cargo planes. Loop at the
list of airplanes and use the downcast technique to identify cargo planes. For those
airplanes for which the downcast was successful, you can then call the GET_CARGO
method defined and implemented in the previous step.
a) See the source code extract from the model solution.
3. Call the GET_MAX_CARGO method from within the DISPLAY_ATTRIBUTES method class
LCL_CARRIER and output the result.
a) See the source code extract from the model solution.
SAPBC401_INH_S3_OPT
REPORT
sapbc401_inh_s3_opt.
TYPE-POOLS icon.
...
*---------------------------------------------------*
*
CLASS lcl_cargo_plane DEFINITION
*---------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING
FROM lcl_airplane.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
iv_cargo
TYPE s_plan_car
160
© Copyright. All rights reserved.
Lesson: Implementing Downcasts Using Inheritance
EXCEPTIONS
wrong_planetype,
display_attributes REDEFINITION,
get_cargo RETURNING value(rv_cargo) TYPE s_plan_car.
PRIVATE SECTION.
DATA:
mv_cargo TYPE s_plan_car.
ENDCLASS.
"lcl_cargo_plane DEFINITION
*----------------------------------------------------*
*
CLASS lcl_cargo_plane IMPLEMENTATION
*----------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
METHOD constructor.
super->constructor(
EXPORTING
iv_name
= iv_name
iv_planetype = iv_planetype
EXCEPTIONS
wrong_planetype = 1 ).
IF sy-subrc <> 0.
RAISE wrong_planetype.
ENDIF.
mv_cargo = iv_cargo.
ENDMETHOD.
"constructor
METHOD display_attributes.
super->display_attributes( ).
WRITE:
/ 'Max Cargo:'(005), AT c_pos_1 mv_cargo
LEFT-JUSTIFIED.
ULINE.
ENDMETHOD.
"display_attributes
METHOD get_cargo.
rv_cargo = mv_cargo.
ENDMETHOD.
ENDCLASS.
"get_cargo
"lcl_cargo_plane IMPLEMENTATION
...
*---------------------------------------------------*
*
CLASS lcl_carrier DEFINITION
*---------------------------------------------------*
CLASS lcl_carrier DEFINITION.
PUBLIC SECTION.
METHODS:
constructor IMPORTING iv_name TYPE string,
display_attributes,
add_airplane IMPORTING io_plane
TYPE REF TO lcl_airplane.
© Copyright. All rights reserved.
161
Unit 3: Inheritance and Casting
PRIVATE SECTION.
DATA:
mv_name
TYPE string,
mt_airplanes TYPE TABLE OF REF TO lcl_airplane.
METHODS:
display_airplanes,
get_max_cargo RETURNING value(rv_max_cargo)
TYPE s_plan_car.
ENDCLASS.
"lcl_carrier DEFINITION
*--------------------------------------------------*
*
CLASS lcl_carrier IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
ENDMETHOD.
"constructor
METHOD display_attributes.
DATA:
lv_max_cargo TYPE s_plan_car.
SKIP 2.
WRITE: icon_flight AS ICON,
mv_name.
ULINE.
ULINE.
me->display_airplanes( ).
lv_max_cargo = me->get_max_cargo( ).
WRITE: / 'Capacity of biggest cargo plane:'(max),
lv_max_cargo LEFT-JUSTIFIED.
ENDMETHOD.
"display_attributes
METHOD add_airplane.
APPEND io_plane TO mt_airplanes.
ENDMETHOD.
"add_airplane
METHOD display_airplanes.
DATA: lo_plane TYPE REF TO lcl_airplane.
LOOP AT mt_airplanes INTO lo_plane.
lo_plane->display_attributes( ).
ENDLOOP.
ENDMETHOD.
"display_airplanes
METHOD get_max_cargo.
DATA:
lo_plane TYPE REF TO lcl_airplane,
lo_cargo TYPE REF TO lcl_cargo_plane.
LOOP AT mt_airplanes INTO lo_plane.
TRY.
lo_cargo ?= lo_plane.
IF rv_max_cargo < lo_cargo->get_cargo( ).
rv_max_cargo = lo_cargo->get_cargo( ).
ENDIF.
162
© Copyright. All rights reserved.
Lesson: Implementing Downcasts Using Inheritance
*
CATCH cx_sy_move_cast_error.
plane is not a cargo plane - do nothing
ENDTRY.
ENDLOOP.
ENDMETHOD.
"get_max_cargo
ENDCLASS.
© Copyright. All rights reserved.
"lcl_carrier IMPLEMENTATION
163
Unit 3: Inheritance and Casting
Usage of Class Hierarchies
Figure 80: Usage of Class Hierarchies
As early as the modeling phase, you can identify a generalization and specialization
relationship between certain classes. If such a relationship exists between certain classes,
you can use inheritance to represent this in ABAP Objects.
For example, the semantics must be preserved when you redefine methods. Furthermore,
inherited components must be used as intended in the superclass.
Misuse of Inheritance
Figure 81: Examples – Misuse of Inheritance
If you do not have a correct understanding of the semantics of “is a (specific)”, you run the
risk of identifying the wrong places in which to use inheritance. Sometimes the need for
another attribute for a class is incorrectly answered with a specialization.
For example, a superclass called Car, contains the subclasses red Car, blue Car, and so on.
The statement “A red car is a specific car” is correct only at first glance. However, there are
no cars without a color. At most, there are some cars that have not been painted. Therefore,
every car needs the attribute color, assuming that it is relevant to the application. Therefore,
that attribute must be defined in the superclass. There may be contradictions with reality
when you try to implement a method for painting the cars.
164
© Copyright. All rights reserved.
Lesson: Implementing Downcasts Using Inheritance
Note:
Such attributes are also defined as reference variables to a superclass of role
classes. There is one description class for each role. To change the role of an
instance, you then exchange the references to the corresponding role description
instances. Specialist literature also refers to this as a role design pattern.
In some cases, specialization relationships that do not allow for semantics to be retained need
to be identified.
For example, the square class inherits from the rectangle class. If you try to define methods
for the rectangle that change the width and height separately, these methods will not make
sense when applied to the square. Even if the methods are redefined to make the lengths of
the sides uniform, the semantics will be different.
For the same reason, that is, using inheritance only because some required functions are
found in a superclass is also not appropriate.
© Copyright. All rights reserved.
165
Unit 3: Inheritance and Casting
LESSON SUMMARY
You should now be able to:
166
●
Implement downcasts using inheritance
●
Model class hierarchies
© Copyright. All rights reserved.
Unit 3
Learning Assessment
1. Which of the following are the characteristics of inheritance?
Choose the correct answers.
X
A Common components only exist once in the superclass
X
B Components in the subclasses are available in all superclasses
X
C Subclasses contain extensions or changes
X
D Subclasses are not dependent on superclasses
2. A superclass is a generalization of its subclasses.
Determine whether this statement is true or false.
X
True
X
False
3. Suppose that you have a class X that inherits from class Y. After an up-cast a reference
variable that is statically typed TYPE REF TO Y points to an instance of class X. What
components of class X can you access with this reference variable?
Choose the correct answers.
X
A Components defined in class X
X
B Components inherited from class Y
X
C Components redefined in class X
X
D Components defined in class X and redefined in its subclasses
© Copyright. All rights reserved.
167
Unit 3: Learning Assessment
4. When objects from different classes react differently to the same method calls, this is
known as __________.
Choose the correct answer.
X
A objects
X
B events
X
C polymorphism
X
D inheritance
5. A typical use for ________ assignments is to prepare for generic access.
Choose the correct answer.
X
A events
X
B upcast
X
C methods
X
D downcast
6. Which of the following is used to assign a superclass reference to a subclass reference?
Choose the correct answer.
X
A Widening Cast
X
B Narrowing Cast
X
C Redefinition
7. Which of the following is the downcast assignment operator?
Choose the correct answer.
168
X
A =
X
B <>
X
C ?=
X
D =?
© Copyright. All rights reserved.
Unit 3: Learning Assessment
8. Suppose that you have the same class X that inherits from class Y. After a down-cast, a
reference variable that is statically typed TYPE REF TO X points to an instance of class X.
Which of the following components of class X can you access with this reference variable?
Choose the correct answers.
X
A Components defined in class X
X
B Components inherited from class Y
X
C Components redefined in class X
X
D Components defined in class X and redefined in its subclasses
9. What are the advantages of correctly using class hierarchies?
Choose the correct answers.
X
A Centralized maintenance
X
B Safe and generic method of access
X
C Semantics preserved
X
D Intended use of inherited components
© Copyright. All rights reserved.
169
Unit 3
Learning Assessment - Answers
1. Which of the following are the characteristics of inheritance?
Choose the correct answers.
X
A Common components only exist once in the superclass
X
B Components in the subclasses are available in all superclasses
X
C Subclasses contain extensions or changes
X
D Subclasses are not dependent on superclasses
2. A superclass is a generalization of its subclasses.
Determine whether this statement is true or false.
X
True
X
False
3. Suppose that you have a class X that inherits from class Y. After an up-cast a reference
variable that is statically typed TYPE REF TO Y points to an instance of class X. What
components of class X can you access with this reference variable?
Choose the correct answers.
170
X
A Components defined in class X
X
B Components inherited from class Y
X
C Components redefined in class X
X
D Components defined in class X and redefined in its subclasses
© Copyright. All rights reserved.
Unit 3: Learning Assessment - Answers
4. When objects from different classes react differently to the same method calls, this is
known as __________.
Choose the correct answer.
X
A objects
X
B events
X
C polymorphism
X
D inheritance
5. A typical use for ________ assignments is to prepare for generic access.
Choose the correct answer.
X
A events
X
B upcast
X
C methods
X
D downcast
6. Which of the following is used to assign a superclass reference to a subclass reference?
Choose the correct answer.
X
A Widening Cast
X
B Narrowing Cast
X
C Redefinition
7. Which of the following is the downcast assignment operator?
Choose the correct answer.
X
A =
X
B <>
X
C ?=
X
D =?
© Copyright. All rights reserved.
171
Unit 3: Learning Assessment - Answers
8. Suppose that you have the same class X that inherits from class Y. After a down-cast, a
reference variable that is statically typed TYPE REF TO X points to an instance of class X.
Which of the following components of class X can you access with this reference variable?
Choose the correct answers.
X
A Components defined in class X
X
B Components inherited from class Y
X
C Components redefined in class X
X
D Components defined in class X and redefined in its subclasses
9. What are the advantages of correctly using class hierarchies?
Choose the correct answers.
172
X
A Centralized maintenance
X
B Safe and generic method of access
X
C Semantics preserved
X
D Intended use of inherited components
© Copyright. All rights reserved.
UNIT 4
Interfaces and Casting
Lesson 1
Defining and Implementing Local Interfaces
Exercise 11: Define and Implement a Local Interface
174
179
Lesson 2
Implementing Polymorphism Using Interfaces
Exercise 12: Implement Polymorphism Using Interfaces
189
193
Lesson 3
Integrating Class Models Using Interfaces
Exercise 13: Integrate Class Models Using Interfaces
200
203
UNIT OBJECTIVES
●
Explain the use of interfaces
●
Create generalization and specialization relationships using interfaces
●
Implement polymorphism using interfaces
●
Implement downcasts with interfaces
●
Integrate different submodels using interfaces
●
Create and use interface hierarchies
© Copyright. All rights reserved.
173
Unit 4
Lesson 1
Defining and Implementing Local Interfaces
LESSON OVERVIEW
This lesson explains the method of defining and implementing interfaces.
Business Example
As a developer, you need to create interfaces and implement them in your model in ABAP
objects. For this reason, you require the following knowledge:
●
An understanding of interface use
●
An understanding of interface definition
●
An understanding of interface implementation
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Explain the use of interfaces
●
Create generalization and specialization relationships using interfaces
Use of Interfaces
Figure 82: Central Definition of Shared Components
Interfaces differ from regular inheritance in their areas of use. However, in terms of
programming, there are hardly any differences between interfaces and regular inheritance.
174
© Copyright. All rights reserved.
Lesson: Defining and Implementing Local Interfaces
Interfaces can be seen as superclasses that cannot be instantiated, do not contain
implementations, and have only public components. You can simulate multiple inheritances
using interfaces.
In ABAP Objects, interfaces primarily serve to define uniform interface protocols for services.
Various classes can implement these services in different ways, but you need to keep the
same semantics. Therefore, interfaces contain no implementations.
In ABAP Objects, the same components can generally be defined in interfaces and classes. To
recognize the semantic differences from regular inheritance, you can concentrate on the
following use cases.
For example, you want to allow multiple classes to implement a service in different ways, but
using the same method names and a uniform signature. With regular inheritance, you would
define such a method in the shared superclass. However, if you cannot model a superclass for
inheritance suitably, you need to define an interface and then define the method in the
interface. Therefore, you can compare this case with a generalization relationship within a
superclass.
Definition of Interfaces
Figure 83: Client Defines The Protocol
Compared to regular inheritance, the distribution of roles in interfaces is sometimes different.
The user generally defines the interfaces. In these interfaces, the user describes both
technically and semantically the services that the user wants the providers to offer. Each
class can now decide for itself whether it serves the interface, that is, whether it actually
offers the services defined in the interface. Therefore, this case is similar to a specialization
relationship with a subclass.
As with regular inheritance, access to these services defined in the interface is then usually
generic, that is, access to the services uses a reference that is typed on the interface. As in
inheritance, polymorphism can also be implemented in interfaces.
© Copyright. All rights reserved.
175
Unit 4: Interfaces and Casting
Generic Access to Interface Components
Figure 84: Interfaces in UML Notation
In UML, you represent the interfaces in the same way as you represent classes. However, in
addition to the interface name, you use notation «interface». You represent the use of an
interface by a dotted line with a two-sided arrow from the user to the interface. The keyword
«uses» is optional.
Generalization and Specialization Relationships Using Interfaces
Figure 85: Defining and Implementing an Interface
176
© Copyright. All rights reserved.
Lesson: Defining and Implementing Local Interfaces
In ABAP Objects, you can define the same components in an interface as you can in classes.
However, interfaces do not know the visibility levels of their components, that is, all the
components of an interface are public.
Classes implement interfaces in the following ways:
●
Interface name
The interface name is listed in the definition part of the class with the INTERFACES
statement. This occurs in the PUBLIC SECTION, that is, interfaces can only be
implemented publicly.
●
Interface methods
The interface methods are implemented in the implementation part of the class.
●
Interface components
The components defined in the interface are addressed in the implementation part of the
class.
Interface components are distinguished from the other components in the implementing
class by prefixing the interface name followed by a tilde (~), which is the interface resolution
operator.
interface_name~component_name
Access to Interface Components
Figure 86: Addressing Interface Components Using Object References
You can access interface components only by using an object reference whose class
implements the interface. You use the interface resolution operator (~) to access the
interface components in the implementation part of the class.
© Copyright. All rights reserved.
177
Unit 4: Interfaces and Casting
Figure 87: Simplifying Access to Interface Components with Alias Names
To simplify access to interface components, you can use alias names. These alias names can
appear in the definition part of a class. The use of alias names is subject to the visibility
restriction of the defining class.
An alias for an interface method is defined as follows:
ALIASES a_1 FOR lif_1~method_1.
The interface method lif_1~method_1 can be addressed with the shorter form ref->a_1.
178
© Copyright. All rights reserved.
Unit 4
Exercise 11
Define and Implement a Local Interface
Business Example
You need to add a car rental company to your program. The car rental company together with
the existing airline needs to be added into the travel agency class as the travel agency’s
business partners. To add these business partners, you need a generic access to airlines and
car rental companies. Instead of defining a common superclass, you need to define an
interface with generic services, which is then implemented in the classes for airlines and car
rental companies.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Define and implement the interface in your existing class for airlines.
Template: SAPBC401_INH_S3
Solution: SAPBC401_INT_S1
Create an INCLUDE Program from the Main Program
To increase the legibility of your program, split the source code into a main program and one
INCLUDE program.
The INCLUDE program must contain all the local class definitions and implementations. The
declaration of reference variables and the START-OF-SELECTION event block should remain
in the main program.
Note:
This distribution does not follow the recommended use of INCLUDES in ABAP
programs. According to the programming guidelines, the class definitions and
data declarations should go to the TOP-INCLUDE, the implementations to a PINCLUDE, and the START-OF-SELECTION event block to an E-INCLUDE.
1. Complete your program ZBC401_##_MAIN or copy the sample solution from the previous
exercise.
2. In your main program, implement the usage of a new INCLUDE program (recommended
name: ZBC401_##_CARRIER). Create the INCLUDE through forward navigation. You can
do this by double-clicking the name of the INCLUDE.
3. Cut the definition and implementation sections of all four local classes from the main
program and paste them on to the newly created include program.
© Copyright. All rights reserved.
179
Unit 4: Interfaces and Casting
4. Where do you have to place the INCLUDE statement to avoid syntax errors?
5. Activate and test your program.
Define an Interface
Define an interface with the DISPLAY_PARTNER method to later offer generic access options
to potential clients in the travel agency example.
1. Create a new INCLUDE (recommended name: ZBC401_##_AGENCY) and define an
interface LIF_PARTNER in the new INCLUDE.
2. Check the entire program for syntactical correctness and activate it.
The interface should contain the DISPLAY_PARTNER instance method. The instance
method should not have any parameters. Later, your task will be to display business
partner attributes.
Implement an Interface
The LCL_CARRIER class should make the services defined in the interface available to
potential clients. To achieve this, class LCL_CARRIER needs to implement the interface and,
therefore, the interface method DISPLAY_PARTNER.
1. In the definition of LCL_CARRIER, declare the newly created interface.
2. Implement the coding of the DISPLAY_PARTNER interface method in the LCL_CARRIER
class. As is evident from the name of the method, the data, or attributes of this business
partner should be displayed here. Consider the possible solutions and execute the most
suitable approach.
Check the entire application for syntactical correctness and activate your application.
Hint:
The performance of the application will still not change at this point; the
results can be seen only in the later tasks.
Test the Interface
Test the interface implemented in the LCL_CARRIER class by calling the interface method
from the main program.
1. In the main program, remove the call for the DISPLAY_ATTRIBUTES method of the
LCL_CARRIER class. Replace it with a call for the DISPLAY_PARTNER interface method.
2. What would be the objective of such a call at this point of the exercise be, or in other
words, what does the option of this interface method call bring out of the main program in
contrast with a conventional method call?
3. After a successful test, turn this method call into a comment so that it becomes
ineffective.
180
© Copyright. All rights reserved.
Lesson: Defining and Implementing Local Interfaces
Hint:
The generic use of the interface methods with another class takes place in
the next steps of the exercise. The performance of the entire application will
still not change at this point; the results can be seen only in later tasks.
© Copyright. All rights reserved.
181
Unit 4
Solution 11
Define and Implement a Local Interface
Business Example
You need to add a car rental company to your program. The car rental company together with
the existing airline needs to be added into the travel agency class as the travel agency’s
business partners. To add these business partners, you need a generic access to airlines and
car rental companies. Instead of defining a common superclass, you need to define an
interface with generic services, which is then implemented in the classes for airlines and car
rental companies.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Define and implement the interface in your existing class for airlines.
Template: SAPBC401_INH_S3
Solution: SAPBC401_INT_S1
Create an INCLUDE Program from the Main Program
To increase the legibility of your program, split the source code into a main program and one
INCLUDE program.
The INCLUDE program must contain all the local class definitions and implementations. The
declaration of reference variables and the START-OF-SELECTION event block should remain
in the main program.
Note:
This distribution does not follow the recommended use of INCLUDES in ABAP
programs. According to the programming guidelines, the class definitions and
data declarations should go to the TOP-INCLUDE, the implementations to a PINCLUDE, and the START-OF-SELECTION event block to an E-INCLUDE.
1. Complete your program ZBC401_##_MAIN or copy the sample solution from the previous
exercise.
a) Carry out this step in the usual manner. Additional information about the copying of
programs is available in the SAP Library.
2. In your main program, implement the usage of a new INCLUDE program (recommended
name: ZBC401_##_CARRIER). Create the INCLUDE through forward navigation. You can
do this by double-clicking the name of the INCLUDE.
a) See the source text excerpt from the model solution.
3. Cut the definition and implementation sections of all four local classes from the main
program and paste them on to the newly created include program.
a) See the source text excerpt from the model solution.
182
© Copyright. All rights reserved.
Lesson: Defining and Implementing Local Interfaces
4. Where do you have to place the INCLUDE statement to avoid syntax errors?
The INCLUDE statement has to be placed before the declaration of reference variables.
Otherwise, the class definitions are not known in the declaration of reference variables.
5. Activate and test your program.
a) Carry out this step in the usual manner. Additional information about the copying of
programs is available in the SAP Library.
Define an Interface
Define an interface with the DISPLAY_PARTNER method to later offer generic access options
to potential clients in the travel agency example.
1. Create a new INCLUDE (recommended name: ZBC401_##_AGENCY) and define an
interface LIF_PARTNER in the new INCLUDE.
a) See the source text excerpt from the model solution.
2. Check the entire program for syntactical correctness and activate it.
The interface should contain the DISPLAY_PARTNER instance method. The instance
method should not have any parameters. Later, your task will be to display business
partner attributes.
a) See the source text excerpt from the model solution.
Implement an Interface
The LCL_CARRIER class should make the services defined in the interface available to
potential clients. To achieve this, class LCL_CARRIER needs to implement the interface and,
therefore, the interface method DISPLAY_PARTNER.
1. In the definition of LCL_CARRIER, declare the newly created interface.
a) See the source text excerpt from the model solution.
2. Implement the coding of the DISPLAY_PARTNER interface method in the LCL_CARRIER
class. As is evident from the name of the method, the data, or attributes of this business
partner should be displayed here. Consider the possible solutions and execute the most
suitable approach.
Check the entire application for syntactical correctness and activate your application.
Hint:
The performance of the application will still not change at this point; the
results can be seen only in the later tasks.
a) See the source text excerpt from the model solution.
Test the Interface
Test the interface implemented in the LCL_CARRIER class by calling the interface method
from the main program.
1. In the main program, remove the call for the DISPLAY_ATTRIBUTES method of the
LCL_CARRIER class. Replace it with a call for the DISPLAY_PARTNER interface method.
a) See the source text excerpt from the model solution.
© Copyright. All rights reserved.
183
Unit 4: Interfaces and Casting
2. What would be the objective of such a call at this point of the exercise be, or in other
words, what does the option of this interface method call bring out of the main program in
contrast with a conventional method call?
Apart from the detailed and longer syntax of this call, the call of the interface method can
be replaced by an ordinary instance method call from, for example,
DISPLAY_ATTRIBUTES. At this point in the exercise, this call does not seem altogether
sensible.
3. After a successful test, turn this method call into a comment so that it becomes
ineffective.
Hint:
The generic use of the interface methods with another class takes place in
the next steps of the exercise. The performance of the entire application will
still not change at this point; the results can be seen only in later tasks.
a) See the source text excerpt from the model solution.
Main program: SAPBC401_INT_S1
REPORT
sapbc401_int_s1.
TYPE-POOLS icon.
INCLUDE bc401_int_s1_agency.
INCLUDE bc401_int_s1_carrier.
DATA:
go_carrier
go_airplane
go_cargo
go_passenger
gv_count
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
i.
TO
TO
TO
TO
lcl_carrier,
lcl_airplane,
lcl_cargo_plane,
lcl_passenger_plane,
START-OF-SELECTION.
*******************
***** Create Carrier ************************************
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly-Travel'.
***** Passenger Plane
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
go_carrier->add_airplane( go_passenger ).
ENDIF.
184
© Copyright. All rights reserved.
Lesson: Defining and Implementing Local Interfaces
***** cargo Plane
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
go_carrier->add_airplane( go_cargo ).
ENDIF.
*** output carrier (including list of airplanes)
* only for testing:
* call interface method for the carrier
*
go_carrier->lif_partner~display_partner( ).
go_carrier->display_attributes( ).
Include BC401_INT_S1_AGENCY
INTERFACE lif_partner.
METHODS display_partner.
ENDINTERFACE.
Include BC401_INT_S1_CARRIER
*---------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*---------------------------------------------------*
CLASS lcl_airplane DEFINITION.
...
ENDCLASS.
"lcl_airplane DEFINITION
*---------------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
...
ENDCLASS.
"lcl_airplane IMPLEMENTATION
*----------------------------------------------------*
*
CLASS lcl_cargo_plane DEFINITION
*----------------------------------------------------*
*
*----------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING
FROM lcl_airplane.
...
ENDCLASS.
"lcl_cargo_plane DEFINITION
*--------------------------------------------------*
*
CLASS lcl_cargo_plane IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
...
© Copyright. All rights reserved.
185
Unit 4: Interfaces and Casting
ENDCLASS.
"lcl_cargo_plane IMPLEMENTATION
*--------------------------------------------------*
*
CLASS lcl_passenger_plane DEFINITION
*--------------------------------------------------*
CLASS lcl_passenger_plane DEFINITION INHERITING FROM lcl_airplane.
...
ENDCLASS.
"lcl_passenger_plane DEFINITION
*---------------------------------------------------*
*
CLASS lcl_passenger_plane IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
...
ENDCLASS.
"lcl_passenger_plane IMPLEMENTATION
*----------------------------------------------------*
*
CLASS lcl_carrier DEFINITION
*----------------------------------------------------*
CLASS lcl_carrier DEFINITION.
PUBLIC SECTION.
INTERFACES:
lif_partner.
METHODS:
constructor IMPORTING iv_name TYPE string,
display_attributes,
add_airplane IMPORTING io_plane TYPE
REF TO lcl_airplane.
PRIVATE SECTION.
DATA:
mv_name
TYPE string,
mt_airplanes TYPE TABLE OF REF TO lcl_airplane.
METHODS:
display_airplanes.
ENDCLASS.
"lcl_carrier DEFINITION
*---------------------------------------------------*
*
CLASS lcl_carrier IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
ENDMETHOD.
"constructor
METHOD display_attributes.
SKIP 2.
WRITE: icon_flight AS ICON,
mv_name.
ULINE.
186
© Copyright. All rights reserved.
Lesson: Defining and Implementing Local Interfaces
ULINE.
me->display_airplanes( ).
ENDMETHOD.
"display_attributes
METHOD add_airplane.
APPEND io_plane TO mt_airplanes.
ENDMETHOD.
"add_airplane
METHOD display_airplanes.
DATA: lo_plane TYPE REF TO lcl_airplane.
LOOP AT mt_airplanes INTO lo_plane.
lo_plane->display_attributes( ).
ENDLOOP.
ENDMETHOD.
"display_airplanes
METHOD lif_partner~display_partner.
me->display_attributes( ).
ENDMETHOD.
"lif_partner~display_partner
ENDCLASS.
© Copyright. All rights reserved.
"lcl_carrier IMPLEMENTATION
187
Unit 4: Interfaces and Casting
LESSON SUMMARY
You should now be able to:
188
●
Explain the use of interfaces
●
Create generalization and specialization relationships using interfaces
© Copyright. All rights reserved.
Unit 4
Lesson 2
Implementing Polymorphism Using Interfaces
LESSON OVERVIEW
This lesson explains polymorphism and implementing polymorphism using interfaces.
Business Example
As a developer, you need to create interfaces and implement polymorphism in your ABAP
Objects project. For this reason, you require the following knowledge:
●
An understanding of polymorphism
●
An understanding of polymorphism in interface implementation
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement polymorphism using interfaces
Polymorphism with Interfaces
Figure 88: Upcast with Interface References
An interface reference can only refer to instances of classes that have implemented the
interface because interfaces themselves cannot be instantiated. As in regular inheritance, you
must use upcast to copy a reference to the interface reference variable to perform
polymorphism with interfaces.
© Copyright. All rights reserved.
189
Unit 4: Interfaces and Casting
If the class has implemented the interface, it is certain that all the components that can be
accessed syntactically after the cast assignment are available in the instance. A user can
address the instance of the implementing class using the interface. The prefixing of the
interface name and the interface resolution operator is omitted. However, the user is
restricted to using the components from the interface.
In the example, the DISPLAY_PARTNER and CHECK_AVAILABILITY methods of the
LIF_PARTNER interface can be accessed only after assigning the reference variable
GO_PARTNER. It is not possible to access the specific components of the instance from the
LCL_RENTAL (GET_NAME in the above example) class using the GO_PARTNER reference
variable.
Therefore, the view is narrowed or, at least, remains unchanged. That is why you describe this
type of assignment of reference variables as upcast. There is a switch from a view of several
components to a view of only a few components. The target reference can, of course, accept
more dynamic types after the assignment, than it could before. Therefore, the term widening
cast is also suitable.
Generic Access with Interfaces
Figure 89: Row Type of the Internal Table in the Application Example
A typical area of use for upcast assignments is preparation for generic access. A user who is
not interested in the finer points of the instances of the class that implement the interface but
who simply wants to address the components defined in the interface, could use an interface
reference for this access.
In the example shown, a travel agency (LCL_TRAVEL_AGENCY) needs to manage the various
kinds of business partners in one list. The developer must therefore assign the row type of the
internal table as the reference to the interface LIF_PARTNER.
The travel agency only wants to request the services in order to display their attributes and
check their availability. The relevant DISPLAY_PARTNER and CHECK_AVAILABILITY methods
are defined in the LIF_PARTNER interface and implemented in all business partner classes.
The objects of different classes (LCL_HOTEL, LCL_RENTAL, and LCL_CARRIER in the
example) can be kept in an internal table, typed with interface references (LIF_PARTNER in
the example). The components defined in the interface can then be accessed uniformly.
190
© Copyright. All rights reserved.
Lesson: Implementing Polymorphism Using Interfaces
For this example, the ADD_PARTNER method is needed. This method copies the references
to all kinds of business partners in the internal table. The import parameter of this method is
already typed as the reference to the interface.
Generic Access Using the Interface Reference
Figure 90: Polymorphism – Generic Access Using the Interface Reference
Polymorphism can also be performed for interfaces. You can use interface references to call
methods and execute different implementations depending on the object of the reference.
The dynamic type of the reference variable is used to search for the implementation of a
method. In the above example, lo_partner->display_partner( ) uses the class of the instance
to which lo_partner actually refers in order to search for the implementation of
display_partner.
The implementation that is executed when DISPLAY_PARTNER is called now depends on the
object to which the interface reference lo_partner currently refers. When objects from
different classes react differently to the same method calls, it is known as polymorphism.
The option of performing polymorphism is one of the main strengths of interfaces. A client
can handle different classes uniformly, regardless of their implementation. The runtime
system searches for the right implementation of a method on behalf of the client.
Polymorphism can be used to write programs that are highly generic, that is, they do not need
to be changed significantly if use cases are added.
In the example, it becomes easy to add a class for boat rentals. For example, the relevant
class with the name LCL_SHIPPING will simply have to implement the LIF_PARTNER interface
and the DISPLAY_PARTNER method defined there. Business partner management can then
easily include ship-owning companies and request them to display their attributes.
© Copyright. All rights reserved.
191
Unit 4: Interfaces and Casting
192
© Copyright. All rights reserved.
Unit 4
Exercise 12
Implement Polymorphism Using Interfaces
Business Example
You need to add a class that uses the previously defined interface. Travel agencies need to
manage various business partners using the interface and access general services of the
business partners.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_INH_T2
Solution: SAPBC401_INT_S2
Define a Local Class
Define a local class for travel agencies.
1. Complete your program ZBC401_##_MAIN or copy the template program with all its
INCLUDES.
2. In the INCLUDE program that contains the definition of the LIF_PARTNER interface, define
and implement the LCL_TRAVEL_AGENCY local class.
Hint:
If you have not copied the template program, you can reduce your typing load
by copying the definition and implementation of the LCL_TRAVEL_AGENCY
class from the SAPBC401_INT_T2 template and include
BC401_INT_T2_AGENCY. You can also create the LCL_TRAVEL_AGENCY
class from scratch, without using templates.
3. As a private class attribute, add an internal table MT_PARTNERS for the buffering of
references to the business partners who have implemented the LIF_PARTNER interface.
4. Define and implement a public method named ADD_PARTNER so that the business
partner references can be added to the MT_PARTNERS list. Define an import parameter
named IO_PARTNER with an appropriate type.
5. Extend the implementation of the DISPLAY_ATTRIBUTES method in a way that it not only
displays information about the travel agency, but also about its business partners. Use the
previously defined DISPLAY_PARTNERS method.
Generate an Instance and Transfer References to the Instance
In the main program, generate a travel agency instance, transfer the references to the airline
to this instance, and add the attributes.
1. In the main program, define a suitably typed reference variable for your new travel agency
class.
© Copyright. All rights reserved.
193
Unit 4: Interfaces and Casting
2. Using the reference, generate an instance of your class LCL_TRAVEL_AGENCY. Decide
how to fill out the attributes.
3. Call the ADD_PARTNER method to transfer the references to the generated airline
instances to the travel agency.
4. Display the attributes of the travel agency (including information about its business
partners) by calling its method DISPLAY_ATTRIBUTES.
194
© Copyright. All rights reserved.
Unit 4
Solution 12
Implement Polymorphism Using Interfaces
Business Example
You need to add a class that uses the previously defined interface. Travel agencies need to
manage various business partners using the interface and access general services of the
business partners.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_INH_T2
Solution: SAPBC401_INT_S2
Define a Local Class
Define a local class for travel agencies.
1. Complete your program ZBC401_##_MAIN or copy the template program with all its
INCLUDES.
a) Carry out this step as usual. For more information, refer to the SAP Library.
2. In the INCLUDE program that contains the definition of the LIF_PARTNER interface, define
and implement the LCL_TRAVEL_AGENCY local class.
Hint:
If you have not copied the template program, you can reduce your typing load
by copying the definition and implementation of the LCL_TRAVEL_AGENCY
class from the SAPBC401_INT_T2 template and include
BC401_INT_T2_AGENCY. You can also create the LCL_TRAVEL_AGENCY
class from scratch, without using templates.
a) Carry out this step in the usual manner. For more information, refer to the SAP Library.
3. As a private class attribute, add an internal table MT_PARTNERS for the buffering of
references to the business partners who have implemented the LIF_PARTNER interface.
a) See the source text excerpt from the model solution.
4. Define and implement a public method named ADD_PARTNER so that the business
partner references can be added to the MT_PARTNERS list. Define an import parameter
named IO_PARTNER with an appropriate type.
a) See the source text excerpt from the model solution.
5. Extend the implementation of the DISPLAY_ATTRIBUTES method in a way that it not only
displays information about the travel agency, but also about its business partners. Use the
previously defined DISPLAY_PARTNERS method.
a) See the source text excerpt from the model solution.
© Copyright. All rights reserved.
195
Unit 4: Interfaces and Casting
Generate an Instance and Transfer References to the Instance
In the main program, generate a travel agency instance, transfer the references to the airline
to this instance, and add the attributes.
1. In the main program, define a suitably typed reference variable for your new travel agency
class.
a) See the source text excerpt from the model solution.
2. Using the reference, generate an instance of your class LCL_TRAVEL_AGENCY. Decide
how to fill out the attributes.
a) See the source text excerpt from the model solution.
3. Call the ADD_PARTNER method to transfer the references to the generated airline
instances to the travel agency.
a) See the source text excerpt from the model solution.
4. Display the attributes of the travel agency (including information about its business
partners) by calling its method DISPLAY_ATTRIBUTES.
a) See the source text excerpt from the model solution.
Include BC401_INT_S2_AGENCY
*&-------------------------------------------------*
*& Include
BC401_INT_S2_AGENCY
*&-------------------------------------------------*
INTERFACE lif_partner.
METHODS:
display_partner.
ENDINTERFACE.
"lif_partner
*--------------------------------------------------*
*
CLASS lcl_travel_agency DEFINITION
*--------------------------------------------------*
CLASS lcl_travel_agency DEFINITION.
PUBLIC SECTION.
METHODS:
constructor IMPORTING iv_name TYPE string,
add_partner IMPORTING io_partner
TYPE REF TO lif_partner,
display_agency_partners,
display_attributes.
PRIVATE SECTION.
DATA:
mv_name
TYPE string,
mt_partners TYPE TABLE OF REF TO lif_partner.
ENDCLASS.
"lcl_travel_agency DEFINITION
*---------------------------------------------------*
*
CLASS lcl_travel_agency IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_travel_agency IMPLEMENTATION.
196
© Copyright. All rights reserved.
Lesson: Implementing Polymorphism Using Interfaces
METHOD display_attributes.
WRITE: / icon_private_files AS ICON,
'Travel Agency:'(007), mv_name.
ULINE.
display_agency_partners( ).
ENDMETHOD.
"display_attributes
METHOD display_agency_partners.
DATA:
lo_partner TYPE REF TO lif_partner.
WRITE 'Here are the partners of the travel agency:'(008).
ULINE.
LOOP AT mt_partners INTO lo_partner.
lo_partner->display_partner( ).
ENDLOOP.
ENDMETHOD.
"display_agency_partners
METHOD constructor.
mv_name = iv_name.
ENDMETHOD.
"constructor
METHOD add_partner.
APPEND io_partner TO mt_partners.
ENDMETHOD.
"add_partner
ENDCLASS.
"lcl_travel_agency IMPLEMENTATION
Main Program SAPBC401_INT_S2
REPORT
sapbc401_int_s2.
TYPE-POOLS icon.
INCLUDE bc401_int_s2_agency.
INCLUDE bc401_int_s2_carrier.
DATA:
go_agency
go_carrier
go_airplane
go_cargo
go_passenger
gv_count
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
REF
i.
TO
TO
TO
TO
TO
lcl_travel_agency,
lcl_carrier,
lcl_airplane,
lcl_cargo_plane,
lcl_passenger_plane,
START-OF-SELECTION.
*******************
***** create travel_agency
CREATE OBJECT go_agency
EXPORTING
iv_name = 'Travel&Smile Travel'.
***** Create Carrier
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly Travel'.
***** Insert carrier into business partner list of
***** travel agency
© Copyright. All rights reserved.
197
Unit 4: Interfaces and Casting
go_agency->add_partner( go_carrier ).
***** Passenger Plane
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
go_carrier->add_airplane( go_passenger ).
ENDIF.
***** cargo Plane
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
go_carrier->add_airplane( go_cargo ).
ENDIF.
***** show attributes of all partners of
***** travel agency
go_agency->display_attributes( ).
198
© Copyright. All rights reserved.
Lesson: Implementing Polymorphism Using Interfaces
LESSON SUMMARY
You should now be able to:
●
Implement polymorphism using interfaces
© Copyright. All rights reserved.
199
Unit 4
Lesson 3
Integrating Class Models Using Interfaces
LESSON OVERVIEW
This lesson explains the method of joining classmodels using interfaces.
Business Example
As a developer, you need to integrate multiple class models of your ABAP Objects project.
For this reason, you require the following knowledge:
●
An understanding of submodels
●
An understanding of integrating submodels
●
An understanding of interface hierarchies
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement downcasts with interfaces
●
Integrate different submodels using interfaces
●
Create and use interface hierarchies
Downcasts with Interfaces
Figure 91: Down-Cast Assignment and Exception Handling in the Application Example
200
© Copyright. All rights reserved.
Lesson: Integrating Class Models Using Interfaces
To assign an interface reference to a class reference where the class has implemented the
interface, you must use the down-cast assignment operator MOVE ... ?TO ... or its short
form ?=. Otherwise, the system would return a message stating that it is not certain that all
components that can be accessed syntactically after the cast assignment are actually
available in the instance. As a rule, the implementing class contains more components than
the interface.
Interface reference variables can contain references to instances of the implementing class at
runtime. After assigning this type of reference back to a reference to the implementing class,
clients are no longer limited to interface components.
This type of reference variable assignment is described as down-casting. The down-casting
view is widened or at least unchanged. This is a switch from a view of a few components to a
view of more components. The term Narrowing Cast is also used.
A typical area of use for down-cast assignments is when specific components of instances
need to be addressed whose references are kept in variables that are typed on the interface. A
user who is interested in the finer points of the instances in implementing classes cannot use
the interface reference because the downcast assignment only allows access to the interface
components. In the example shown in the figure, Down-Cast Assignment and Exception
Handling in the Application Example, a travel agency (LCL_TRAVEL_AGENCY) needs to book
a flight but keeps all the various business partner references in an internal table that was
typed on the interface LIF_PARTNER.
What happens if there is no airline reference in the interface reference GO_PARTNER at
runtime, but the down-cast assignment operator is used to copy the reference to the then
invalid reference GO_CARRIER? In contrast to the up-cast assignment, it is possible that the
static type of the target variable (GO_CARRIER) is neither more general than nor the same as
the dynamic type of the source variables (GO_PARTNER), specifically if GO_PARTNER
contains hotel or car rental references.
The runtime system checks this type of cast before the assignment, whether or not the
current content of the source variable corresponds to the type requirements of the target
variable. Otherwise, an exception that can be handled is triggered, and the original value of
the target variable remains the same. This exception of error class
CX_SY_MOVE_CAST_ERROR can be identified using TRY-ENDTRY and the CATCH
statement.
Another way to prevent this runtime error would be to use runtime type identification (RTTI)
classes. They can be used to determine the dynamic type at runtime and to set a condition for
the cast.
Assignments between interface reference variables, whose typing interfaces are not related
to each other, cannot be checked statically and must, therefore, be performed using downcast. With such an assignment, the system checks at runtime whether the class of the
instance to which the source reference refers also supports the interface with which the
target reference is typed.
Submodel Integration Using Interfaces
Submodels can be integrated with the help of interfaces.
●
The steps to integrate a submodel using interfaces are as follows:
1. Create classes of the submodel.
2. Include given interface into server class of submodel. (Protocol is defined by client.)
© Copyright. All rights reserved.
201
Unit 4: Interfaces and Casting
3. Create instances of server class and refer to them with interface reference.
202
© Copyright. All rights reserved.
Unit 4
Exercise 13
Integrate Class Models Using Interfaces
Business Example
You need to add the car rental company with its vehicles to your own object model. By
implementing the already defined interface, you can ensure that the car rental company can
be added to the list of business partners of the travel agency.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not completed, copy the model solution with all its INCLUDES
from the previous exercise, then add the code from the template program and
INCLUDE file for this program. In the exercises for this course, when the input
values include ##, replace ## with your group number.
Templates:
●
SAPBC401_INT_S2
●
SAPBC401_INT_T3
●
BC401_INT_T3_RENTAL
Solutions:
●
SAPBC401_INT_S3
●
BC401_INT_S3_RENTAL
Add the Vehicle Model to Your Application
Copy the definitions and implementations of classes LCL_RENTAL and the vehicle classes
(LCL_VEHICLE, LCL_TRUCK and LCL_BUS) to your program and create instances of these
classes.
1. Copy the definitions and implementations of classes LCL_RENTAL and the vehicle classes
(LCL_VEHICLE, LCL_TRUCK and LCL_BUS) to your program.
2. In your main program, add reference pointers for LCL_RENTAL, LCL_VEHICLE,
LCL_TRUCK AND LCL_BUS, and create an instance of LCL_RENTAL and a number of
instances of the truck and bus classes. Add all of the vehicles to the rental company’s list
of vehicles by calling method ADD_VEHICLE of LCL_RENTAL.
Hint:
To reduce the typing effort, you can copy and paste the relevant coding from
the main program of SAPBC401_INT_T3.
© Copyright. All rights reserved.
203
Unit 4: Interfaces and Casting
Implement the Business Partner Interface
Implement interface LIF_PARTNER in class LCL_RENTAL.
1. Call method ADD_PARTNER to add the instance of LCL_RENTAL to the travel agency’s list
of business partners.
2. Perform a syntax check. Why does this method call cause a syntax error?
3. Go to the definition part of class LCL_RENTAL and declare the implementation of interface
LIF_PARTNER.
4. Implement the method DISPLAY_PARTNER of the interface LIF_PARTNER in the
implementation section of class LCL_RENTAL.
5. Check, save, and activate the program and INCLUDE files. Then go to the main program
and perform another syntax check
6. Run the program.
Why does the call of ADD_PARTNER now work for the car rental company?
204
© Copyright. All rights reserved.
Unit 4
Solution 13
Integrate Class Models Using Interfaces
Business Example
You need to add the car rental company with its vehicles to your own object model. By
implementing the already defined interface, you can ensure that the car rental company can
be added to the list of business partners of the travel agency.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not completed, copy the model solution with all its INCLUDES
from the previous exercise, then add the code from the template program and
INCLUDE file for this program. In the exercises for this course, when the input
values include ##, replace ## with your group number.
Templates:
●
SAPBC401_INT_S2
●
SAPBC401_INT_T3
●
BC401_INT_T3_RENTAL
Solutions:
●
SAPBC401_INT_S3
●
BC401_INT_S3_RENTAL
Add the Vehicle Model to Your Application
Copy the definitions and implementations of classes LCL_RENTAL and the vehicle classes
(LCL_VEHICLE, LCL_TRUCK and LCL_BUS) to your program and create instances of these
classes.
1. Copy the definitions and implementations of classes LCL_RENTAL and the vehicle classes
(LCL_VEHICLE, LCL_TRUCK and LCL_BUS) to your program.
a) In the Object Navigator, in the unnamed dropdown list on the left of the screen, choose
Package, enter BC401, and press Enter.
b) In the Object Name screen area, expand the Includes node.
c) On the list, right-click the entry BC401_INT_T3_RENTAL, choose Copy.
The Copy Program dialog box displays.
d) In the Copy Program dialog, in the Target Program field, enter ZBC401_##_RENTAL.
Choose Copy.
The Create Object Directory Entrydialog box displays.
© Copyright. All rights reserved.
205
Unit 4: Interfaces and Casting
e) In the Create Object Directory Entrydialog box, enter your package name and choose
Save.
The Prompt for transportable Workbench requestdialog box displays.
f) In the Prompt for transportable Workbench requestdialog box, enter the request name
supplied by your instructor. Choose Continue.
g) Make the copied Include part of your own program.
2. In your main program, add reference pointers for LCL_RENTAL, LCL_VEHICLE,
LCL_TRUCK AND LCL_BUS, and create an instance of LCL_RENTAL and a number of
instances of the truck and bus classes. Add all of the vehicles to the rental company’s list
of vehicles by calling method ADD_VEHICLE of LCL_RENTAL.
Hint:
To reduce the typing effort, you can copy and paste the relevant coding from
the main program of SAPBC401_INT_T3.
a) See the source text excerpt from the model solution.
Implement the Business Partner Interface
Implement interface LIF_PARTNER in class LCL_RENTAL.
1. Call method ADD_PARTNER to add the instance of LCL_RENTAL to the travel agency’s list
of business partners.
a) See the source text excerpt from the model solution.
2. Perform a syntax check. Why does this method call cause a syntax error?
The upcast in the parameter passing of the method does not work because the types
LCL_RENTAL and LIF_PARTNER are not compatible. They will become compatible as
soon as LCL_RENTAL implements the interface.
3. Go to the definition part of class LCL_RENTAL and declare the implementation of interface
LIF_PARTNER.
a) See the source text excerpt from the model solution.
4. Implement the method DISPLAY_PARTNER of the interface LIF_PARTNER in the
implementation section of class LCL_RENTAL.
a) See the source text excerpt from the model solution.
5. Check, save, and activate the program and INCLUDE files. Then go to the main program
and perform another syntax check
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
6. Run the program.
206
© Copyright. All rights reserved.
Lesson: Integrating Class Models Using Interfaces
Why does the call of ADD_PARTNER now work for the car rental company?
Because now the types LCL_RENTAL and LIF_PARTNER are compatible. LCL_RENTAL
implements interface LIF_PARTNER. Any instance of LCL_RENTAL is accepted as a
business partner.
a) To run your program, on the application toolbar, choose the Direct Processingbutton.
Solution: Main Program SAPBC401_INT_S3
REPORT
sapbc401_int_s3.
TYPE-POOLS icon.
INCLUDE bc401_int_s3_agency.
INCLUDE bc401_int_s3_carrier.
INCLUDE bc401_int_s3_rental.
DATA:
go_vehicle
go_truck
go_bus
go_rental
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
TO
TO
TO
TO
lcl_vehicle,
lcl_truck,
lcl_bus,
lcl_rental.
DATA:
go_agency
go_carrier
go_airplane
go_cargo
go_passenger
gv_count
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
REF
i.
TO
TO
TO
TO
TO
lcl_travel_agency,
lcl_carrier,
lcl_airplane,
lcl_cargo_plane,
lcl_passenger_plane,
START-OF-SELECTION.
*******************
******* create travel_agency **********************************
CREATE OBJECT go_agency
EXPORTING
iv_name = 'Travel&Smile Travel'.
******* create rental *****************************************
CREATE OBJECT go_rental
EXPORTING
iv_name = 'Happy Car Rental'.
***** Insert rental company into partner list of travel agency
go_agency->add_partner( go_rental ).
******* create truck ******************************************
CREATE OBJECT go_truck
EXPORTING
iv_make = 'MAN'
iv_cargo = 45.
go_rental->add_vehicle( go_truck ).
******* create bus ******************************************
CREATE OBJECT go_bus
EXPORTING
iv_make
= 'Mercedes'
iv_passengers = 80.
© Copyright. All rights reserved.
207
Unit 4: Interfaces and Casting
go_rental->add_vehicle( go_bus ).
******* create truck ******************************************
CREATE OBJECT go_truck
EXPORTING
iv_make = 'VOLVO'
iv_cargo = 48.
go_rental->add_vehicle( go_truck ).
***** Create Carrier ******************************************
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly-Travel'.
***** Insert carrier into business partner list of travel agency
go_agency->add_partner( go_carrier ).
***** Passenger Plane *****************************************
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
go_carrier->add_airplane( go_passenger ).
ENDIF.
***** cargo Plane *********************************************
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
go_carrier->add_airplane( go_cargo ).
ENDIF.
******* show attributes of all partners of travel_agency ******
go_agency->display_attributes( ).
Solution: Include Program BC401_INT_S3_RENTAL
*---------------------------------------------------------------------*
*
CLASS lcl_vehicle DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_vehicle DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING iv_make TYPE string,
display_attributes.
PRIVATE SECTION.
DATA:
208
© Copyright. All rights reserved.
Lesson: Integrating Class Models Using Interfaces
mv_make TYPE string.
ENDCLASS.
"lcl_vehicle DEFINITION
*---------------------------------------------------------------------*
*
CLASS lcl_vehicle IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS lcl_vehicle IMPLEMENTATION.
METHOD constructor.
mv_make = iv_make.
ENDMETHOD.
"constructor
METHOD display_attributes.
WRITE mv_make.
ENDMETHOD.
"display_attributes
ENDCLASS.
"lcl_vehicle IMPLEMENTATION
*---------------------------------------------------------------------*
*
CLASS lcl_truck DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_truck DEFINITION INHERITING FROM lcl_vehicle.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_make TYPE string
iv_cargo TYPE s_plan_car,
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:
mv_cargo TYPE s_plan_car.
ENDCLASS.
"lcl_truck DEFINITION
*---------------------------------------------------------------------*
*
CLASS lcl_truck IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS lcl_truck IMPLEMENTATION.
METHOD constructor.
super->constructor( iv_make ).
mv_cargo = iv_cargo.
ENDMETHOD.
"constructor
METHOD display_attributes.
WRITE / icon_ws_truck AS ICON.
super->display_attributes( ).
WRITE:
20 'Max. Cargo:'(005),
mv_cargo.
ULINE.
ENDMETHOD.
"display_attributes
ENDCLASS.
© Copyright. All rights reserved.
"lcl_truck IMPLEMENTATION
209
Unit 4: Interfaces and Casting
*---------------------------------------------------------------------*
*
CLASS lcl_bus DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_bus DEFINITION INHERITING FROM lcl_vehicle.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING iv_make
TYPE string
iv_passengers TYPE i,
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:
mv_passengers TYPE i.
ENDCLASS.
"lcl_bus DEFINITION
*---------------------------------------------------------------------*
*
CLASS lcl_bus IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS lcl_bus IMPLEMENTATION.
METHOD constructor.
super->constructor( iv_make ).
mv_passengers = iv_passengers.
ENDMETHOD.
"constructor
METHOD display_attributes.
WRITE: / icon_transportation_mode AS ICON.
super->display_attributes( ).
WRITE:
20 'Max. Passengers: '(006),
mv_passengers.
ULINE.
ENDMETHOD.
"display_attributes
ENDCLASS.
"lcl_bus IMPLEMENTATION
*---------------------------------------------------------------------*
*
CLASS lcl_rental DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_rental DEFINITION.
PUBLIC SECTION.
INTERFACES:
lif_partner.
METHODS:
constructor IMPORTING iv_name TYPE string,
add_vehicle IMPORTING io_vehicle TYPE REF TO lcl_vehicle,
display_attributes.
PRIVATE SECTION.
210
© Copyright. All rights reserved.
Lesson: Integrating Class Models Using Interfaces
DATA:
mv_name TYPE string,
mt_vehicles TYPE TABLE OF REF TO lcl_vehicle.
ENDCLASS.
"lcl_rental DEFINITION
*---------------------------------------------------------------------*
*
CLASS lcl_rental IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS lcl_rental IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
ENDMETHOD.
"constructor
METHOD add_vehicle.
APPEND io_vehicle TO mt_vehicles.
ENDMETHOD.
"add_vehicle
METHOD display_attributes.
DATA:
lo_vehicle TYPE REF TO lcl_vehicle.
WRITE:
/ icon_transport_proposal AS ICON,
mv_name.
ULINE.
ULINE.
LOOP AT mt_vehicles INTO lo_vehicle.
lo_vehicle->display_attributes( ).
ENDLOOP.
ENDMETHOD.
"display_attributes
METHOD lif_partner~display_partner.
me->display_attributes( ).
ENDMETHOD.
"lif_partner~display_partner
ENDCLASS.
© Copyright. All rights reserved.
"lcl_rental IMPLEMENTATION
211
Unit 4: Interfaces and Casting
Implementation of Interface Hierarchies
Figure 92: Interface Hierarchy in the Application Example
An interface implementation strongly resembles regular inheritance. With regular inheritance,
you can define large hierarchies of classes. When we use interfaces instead of classes we call
that interface hierarchies. We would like to illustrate this technique with an application
example.
In this example, you need to know whether it is useful to define a further service for “room
reservation” in the interface LIF_PARTNER. In this case, the classes LCL_CARRIER and
LCL_RENTAL need to implement the appropriate method because they have integrated with
the interface LIF_PARTNER. However, keeping the same semantics is not conceivable for
airlines or car rental companies when we implement the "room reservation" service.
However, because there are several other business partner types for which this
implementation is useful, for example, motels and hotels, the method needs to be defined
centrally and not individually for motels and hotels. If we also need to extend the model with
other accommodation provider types, for example, guesthouses, then the interface hierarchy
needs to be retained.
212
© Copyright. All rights reserved.
Lesson: Integrating Class Models Using Interfaces
Compound Interface in Unified Modeling Language (UML) Notation
Figure 93: Compound Interface in UML Notation
In ABAP Objects, interfaces like regular superclasses can include other interfaces. As with
regular inheritance, the interface hierarchies can be of any depth.
The including interface is a specialization of the included interface. The including interface is
known as a compound interface, represents an extension of the included interface. An
included interface represents a component of another interface and is therefore known as a
component interface. An interface that does not contain other interfaces in itself is known as
an elementary interface.
The UML notation corresponds to the implementation of an elementary interface by a class.
© Copyright. All rights reserved.
213
Unit 4: Interfaces and Casting
Definition and Implementation of Compound Interfaces – Syntax
Figure 94: Definition and Implementation of Compound Interfaces – Syntax
As with regular inheritance, the implementing class only needs to list the compound interface
in order to integrate all components. Nevertheless, the components of the component
interfaces keep their original names:
component_interface_name~component_name
They are, therefore, not prefixed by the name of the compound interface.
All implementations of methods from all higher level interfaces must take place in the first
implementing class. Alias names are suitable for short-form syntax when accessing
components from different interfaces. If the implementing class contains aliases, it provides a
central view of all components.
214
© Copyright. All rights reserved.
Lesson: Integrating Class Models Using Interfaces
Addressing Components in Compound Interfaces – Syntax
Figure 95: Addressing Components in Compound Interfaces – Syntax
You need to address the components from a compound interface and do cast assignments
the same way.
Correct Use of Interfaces
Figure 96: Using Interfaces
Interfaces are used to describe protocols for using components without connecting any
implementation. An intermediate layer is introduced to protect the client from the explicit
server, thereby making the client independent.
Interfaces enable different classes to be handled uniformly, provided those classes have
implemented the interfaces. As with inheritance, you can also perform polymorphism using
interface reference variables.
© Copyright. All rights reserved.
215
Unit 4: Interfaces and Casting
As is the case with regular inheritance, the definition of an interface means the abstraction of
the implementing classes to a specific aspect.
Multiple inheritances can be simulated using interfaces. If several interfaces are included, all
components are available to each of the interfaces and you must implement all methods.
216
© Copyright. All rights reserved.
Lesson: Integrating Class Models Using Interfaces
LESSON SUMMARY
You should now be able to:
●
Implement downcasts with interfaces
●
Integrate different submodels using interfaces
●
Create and use interface hierarchies
© Copyright. All rights reserved.
217
Unit 4: Interfaces and Casting
218
© Copyright. All rights reserved.
Unit 4
Learning Assessment
1. You can access interface components only by using an object reference.
Determine whether this statement is true or false.
X
True
X
False
2. Which of the following is the main strength of interfaces?
Choose the correct answer.
X
A Events
X
B Inheritance
X
C Polymorphism
3. ?= is the down-cast assignment operator.
Determine whether this statement is true or false.
X
True
X
False
4. Suppose a reference variable that is typed to an interface contains an instance reference
of a class that implements this interface and you copy this to a reference variable that is
typed to the class (down-cast). Which of the following components can you access with
this reference variable?
Choose the correct answers.
X
A The components of the interface
X
B The components from the class that are not defined on the interface
X
C All components of the class
X
D The components of the interface for which alias names have been defined
© Copyright. All rights reserved.
219
Unit 4: Learning Assessment
5. Which of the following strongly resembles inheritance?
Choose the correct answer.
X
A Interface
X
B Class
X
C Method
6. Interfaces can include other interfaces.
Determine whether this statement is true or false.
220
X
True
X
False
© Copyright. All rights reserved.
Unit 4
Learning Assessment - Answers
1. You can access interface components only by using an object reference.
Determine whether this statement is true or false.
X
True
X
False
2. Which of the following is the main strength of interfaces?
Choose the correct answer.
X
A Events
X
B Inheritance
X
C Polymorphism
3. ?= is the down-cast assignment operator.
Determine whether this statement is true or false.
X
True
X
False
4. Suppose a reference variable that is typed to an interface contains an instance reference
of a class that implements this interface and you copy this to a reference variable that is
typed to the class (down-cast). Which of the following components can you access with
this reference variable?
Choose the correct answers.
X
A The components of the interface
X
B The components from the class that are not defined on the interface
X
C All components of the class
X
D The components of the interface for which alias names have been defined
© Copyright. All rights reserved.
221
Unit 4: Learning Assessment - Answers
5. Which of the following strongly resembles inheritance?
Choose the correct answer.
X
A Interface
X
B Class
X
C Method
6. Interfaces can include other interfaces.
Determine whether this statement is true or false.
222
X
True
X
False
© Copyright. All rights reserved.
UNIT 5
Object-Oriented Events
Lesson 1
Implementing Events in Local Classes
Exercise 14: Implement Events in Local Classes
224
233
Lesson 2
Implementing Events in Local Interfaces
Exercise 15: Implement Handling of Interface Events
246
247
UNIT OBJECTIVES
●
Implement event-controlled method calls
●
Trigger and handle events
●
Register for events
●
Explain visibility sections in event handling
●
Implement events in local interfaces
© Copyright. All rights reserved.
223
Unit 5
Lesson 1
Implementing Events in Local Classes
LESSON OVERVIEW
This lesson explains the method of implementing events in local classes.
Business Example
As a developer, you need to implement event-controlled behavior for your model in ABAP
Objects. For this reason, you require the following knowledge:
●
An understanding of how to define and trigger events
●
An understanding of how to events
●
An understanding of how to register events
●
An understanding of how to implement events in local classes
LESSON OBJECTIVES
After completing this lesson, you will be able to:
224
●
Implement event-controlled method calls
●
Trigger and handle events
●
Register for events
●
Explain visibility sections in event handling
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
Event-Controlled Method Calls
Figure 97: Event-Controlled Method Calls
Besides attributes and methods, classes and their instances can also contain another type of
component called events.
Instance events can be triggered by the instances of the class, but static events can be
triggered by the class itself.
Events can also be defined as interface components.
Given the right circumstances, handler methods react to the triggering of this event. This
means that the runtime system may call these handler methods after the event has been
triggered. In other words, the client usually does not call the handler method directly.
This results in a completely different modeling concept. While you are developing the class
that triggers the event, you do not need to know anything about the class that is handling it.
The triggering class sends a specific message to all classes and, if required, their instances. At
the time of development, type of handlers and the number of handlers, which may be used are
not known.
Because of the definition of the handler method, the range of possible results can be
narrowed down. However, the results, which may occur can be determined only after the
event has been triggered.
An event can have exporting parameters, which means that, in contrast to the explicit method
call, the calling program determines the protocol.
In this application example, after an instance in the Vehicle class is created, the instance
triggers the event Vehicle Created.
This event is received by several instances and is processed differently by each instance. For
example, the rental car company handles the purchasing of a vehicle, while the vehicle
registration office registers the purchased vehicle.
© Copyright. All rights reserved.
225
Unit 5: Object-Oriented Events
Caution:
Do not confuse this concept of events in object-oriented programming with
events in the ABAP runtime system, such as LOAD-OF-PROGRAM, START-OFSELECTION, and so on. Also, do not confuse this concept with background
processing or workflow control.
Event Handling in a UML Class Diagram
Figure 98: Event Handling in a UML Class Diagram
In UML class diagrams, a dotted arrow with the stereotype «handlesEventOf» points from the
handling class to the triggering class. The event definition and signature only appear implicitly
in the handling class within the handler method. The handler methods are separated from the
other methods using the stereotype «eventHandler».
226
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
Event Triggering and Handling
Figure 99: Defining and Triggering Events – Syntax
Depending on the status of your application, you may not need to program every step every
time. The separation of cause and effect in your programming must be reflected in the way
you construct complex applications. Often, the event is already triggered, and all you have to
do is create another event handler.
Within a class, instance events are defined using the EVENTS statement, while static events
are defined using the CLASS-EVENTS statement. Events can only have exporting parameters,
which must be passed by value.
A class or instance can trigger an event at runtime using the RAISE EVENT statement. Both
instance events and static events can be triggered in instance methods. In static methods,
you can only trigger static events.
When an event is triggered, the handler methods that are registered to this event are called in
sequence. These handler methods can trigger more events of their own.
© Copyright. All rights reserved.
227
Unit 5: Object-Oriented Events
Handling Events – Syntax
Figure 100: Handling Events – Syntax
Instance events or static methods can be defined within a class to handle events. To do so,
you must specify the event using the FOR EVENT statement, and the class or interface in
which the event was defined using the OF statement.
If the event contains exporting parameters and you want to be able to address these
syntactically, you must have specified the exporting parameters immediately after
IMPORTING in the definition of the method. The handler method’s signature exporting
parameters are all that are allowed to be included explicitly than the exporting parameters of
the associated event. The parameters are typed by the handler method during the definition
of the event. The object that triggers the event determines the protocol.
In addition to the explicitly defined exporting parameters, the predefined importing parameter
SENDER can always be listed. By using that parameter, you can place a reference to the
event-trigger object into the handler method.
Therefore, handler methods are usually called by triggered events RAISE EVENT. However,
they can also be called explicitly (CALL METHOD).
To Trigger and Handle Events
This procedure summarizes all of the required programming steps for event controlling:
1. Define an event in a class. The syntax for this is EVENTS eventname, CLASS-EVENTS
eventname.
2. Trigger the event in in a method of this class. The syntax for this is RAISE EVENT
eventname.
3. Define and implement the handler method in the same or another. The syntax for this is
[CLASS -] METHODS … FOR EVENT …. OF.
228
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
4. Register handler object or handler class to events at runtime. The syntax for this is SET
HANDLER.
Event Handler Registration
Figure 101: Event Handler Registration
The definition of the handler method only specifies how and to which event of which class the
method will react. At runtime, it needs to be determined which possible reactions will actually
take place and when each of these reactions will happen.
When triggering instance events, you also have to specify which event the reaction will trigger.
If instance methods are set to carry out the reaction, you also have to specify which instances
will perform the reaction.
These specifications are collectively known as registration. Registration is always carried out
using the trigger. When the event is triggered, the runtime uses the registrations of the trigger
to determine which event handler methods need to be called.
In this example, handler methods are defined for the event of the vehicle class, the car rental
class, and the vehicle registration class. However, you can only predetermine which car rental
instances and vehicle registration instances will react to which vehicle instance, and when
they will do so.
Registrations can also be revoked.
© Copyright. All rights reserved.
229
Unit 5: Object-Oriented Events
Registering Event Handling – Syntax
Figure 102: Registering Event Handling – Syntax
Events are registered using the SET HANDLER statement. Registration is only active at
program runtime.
With instance events, FOR is followed by the reference to the object that triggers the event.
The addition ACTIVATION 'X' is optional during registration. To undo the registration, use
ACTIVATION ' '.
You can register several methods with one SET HANDLER statement:
SET HANDLER ref_handler_1->on_eventname_1 ...
ref_handler_n->on_eventname_n FOR ...
Caution:
If several methods were registered to one event, the sequence in which the event
handler methods are called is not defined, that is, there is no guaranteed
sequence in which the event handler methods are called.
With the addition ALL INSTANCES an event handler can be registered for all instances of the
class that defines the instance event. This is the only way to register handlers for instances
that have not yet been created.
230
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
Event Handler Deregistration
Figure 103: Registration/Deregistration Handler Tables
Every object or class that defines events has an internal table known as the handler table. All
handler methods that are registered to the various events are listed within the handler table.
For instance methods, the handler table also contains references to the registered objects.
Hint:
Objects that are registered for event handling are not deleted by the garbage
collector, even if there are no remaining references to them.
Note:
It is possible to add or remove event handlers for a given event while an event
handler for this exact event is executed. If a new event handler is registered, then
this event handler is added to the end of the sequence and executed when its time
comes. If an existing event handler is deregistered, then this handler is deleted
immediately from the event handler method sequence.
Visibility Sections in Event Handling
Events are subject to the visibility concept and can therefore be considered public, protected,
or private. Event handler methods also have visibility attributes.
Visibility Sections of Events
●
The visibility of an event defines where the event can be handled
:
© Copyright. All rights reserved.
231
Unit 5: Object-Oriented Events
-
PUBLIC
Event can be handled anywhere.
-
PROTECTED
Event can only be handled within its own class or its subclasses.
-
PRIVATE
Event can only be handled within its own class.
Visibility Sections of Handler Methods
●
The visibility of an event handler defines where the handler method can be registered
:
-
PUBLIC
Handler method can be registered anywhere in the program.
-
PROTECTED
Handler method can be registered within its own class or its subclasses.
-
PRIVATE
Handler method can only be registered within its own class.
Event-handler methods can only have the same or more restricted visibility than the events
they refer to.
232
© Copyright. All rights reserved.
Unit 5
Exercise 14
Implement Events in Local Classes
Business Example
You need to include airplane and vehicle references in the airline and the car rental company’s
lists. This process is to be event-controlled.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_INT_S3
Solution: SAPBC401_EVE_S1
Trigger and Handle an Event for Airplanes
Define an event for the creation of an airplane. Trigger and handle the event so that the
reference to the airplane is entered into the airline’s list of airplanes.
1. Use your program ZBC401_##_MAIN or copy the template program.
Identify the class that is suitable for triggering the event and the class that you should use
for handling the event. Use your UML diagram if necessary.
2. Define the public event AIRPLANE_CREATED in class LCL_AIRPLANE. Choose a suitable
method of LCL_AIRPLANE and fire the event in its implementation.
3. In class LCL_CARRIER, define a handler method for the event that you just defined
(recommended name: ON_AIRPLANE_CREATED).
4. Implement the handler method so that the new airplane is added to the airplane list of the
carrier.
Hint:
You can do that either directly or by calling the existing method
ADD_AIRPLANE. In both cases, ensure that the same airplane cannot be
added to the list again. Therefore, either delete method ADD_AIRPLANE or
make it private.
5. Remove all calls of ADD_AIRPLANE from your main program.
6. Register the new handler method, so that every airplane created was added into the
airplane list by the airline.
Note:
Although this model is unrealistic, we will use it for the time being. You can
create a different rule for entering the airplane later.
© Copyright. All rights reserved.
233
Unit 5: Object-Oriented Events
7. Where could the SET HANDLER statement be executed in the example given? Could this
also be done from the main program?
8. What would the syntax have to be in case the handler would have been set from the main
program?
9. Observe the execution of the program in the ABAP Debugger.
Trigger and Handle an Event for Vehicles
Define an event for the creation of a vehicle. Trigger and handle the event so that the
reference to the vehicle is entered into the car rental company’s list of vehicles.
1. Remove all calls of ADD_VEHICLE from your main program.
2. Define the public event VEHICLE_CREATED in class LCL_VEHICLE and fire the event in the
implementation of the constructor.
3. In class LCL_RENTAL, define and implement a handler method for the event that you just
defined (recommended name: ON_VEHICLE_CREATED).
4. Register the new handler method, so that every vehicle was added into the vehicle list by
the car rental company.
Note:
Although this model is unrealistic, we will use it for the time being. A different
rule for entering the vehicles could be created later.
5. Observe the execution of the program in the ABAP Debugger.
234
© Copyright. All rights reserved.
Unit 5
Solution 14
Implement Events in Local Classes
Business Example
You need to include airplane and vehicle references in the airline and the car rental company’s
lists. This process is to be event-controlled.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_INT_S3
Solution: SAPBC401_EVE_S1
Trigger and Handle an Event for Airplanes
Define an event for the creation of an airplane. Trigger and handle the event so that the
reference to the airplane is entered into the airline’s list of airplanes.
1. Use your program ZBC401_##_MAIN or copy the template program.
Identify the class that is suitable for triggering the event and the class that you should use
for handling the event. Use your UML diagram if necessary.
a) Carry out this step in the usual manner. For more information refer to the SAP Library.
2. Define the public event AIRPLANE_CREATED in class LCL_AIRPLANE. Choose a suitable
method of LCL_AIRPLANE and fire the event in its implementation.
a) Refer source code extract from the model solution.
3. In class LCL_CARRIER, define a handler method for the event that you just defined
(recommended name: ON_AIRPLANE_CREATED).
a) Refer source code extract from the model solution.
4. Implement the handler method so that the new airplane is added to the airplane list of the
carrier.
Hint:
You can do that either directly or by calling the existing method
ADD_AIRPLANE. In both cases, ensure that the same airplane cannot be
added to the list again. Therefore, either delete method ADD_AIRPLANE or
make it private.
a) Refer source code extract from the model solution.
5. Remove all calls of ADD_AIRPLANE from your main program.
a) Refer source code extract from the model solution.
6. Register the new handler method, so that every airplane created was added into the
airplane list by the airline.
© Copyright. All rights reserved.
235
Unit 5: Object-Oriented Events
Note:
Although this model is unrealistic, we will use it for the time being. You can
create a different rule for entering the airplane later.
a) Refer source code extract from the model solution.
7. Where could the SET HANDLER statement be executed in the example given? Could this
also be done from the main program?
Either in the constructor of LCL_CARRIER or in the main program after the creation of the
LCL_CARRIER but before the creation of the first airplane.
8. What would the syntax have to be in case the handler would have been set from the main
program?
SET HANDLER go_carrier->on_airplane_created FOR ALL INSTANCES.
9. Observe the execution of the program in the ABAP Debugger.
a) Carry out this step in the usual manner. Additional information is available in the SAP
Library.
Trigger and Handle an Event for Vehicles
Define an event for the creation of a vehicle. Trigger and handle the event so that the
reference to the vehicle is entered into the car rental company’s list of vehicles.
1. Remove all calls of ADD_VEHICLE from your main program.
a) Refer source code extract from the model solution.
2. Define the public event VEHICLE_CREATED in class LCL_VEHICLE and fire the event in the
implementation of the constructor.
a) Refer source code extract from the model solution.
3. In class LCL_RENTAL, define and implement a handler method for the event that you just
defined (recommended name: ON_VEHICLE_CREATED).
a) Refer source code extract from the model solution.
4. Register the new handler method, so that every vehicle was added into the vehicle list by
the car rental company.
Note:
Although this model is unrealistic, we will use it for the time being. A different
rule for entering the vehicles could be created later.
a) Refer source code extract from the model solution.
5. Observe the execution of the program in the ABAP Debugger.
a) Carry out this step in the usual manner. Additional information about the ABAP
Debugger is available in the SAP Library.
236
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
Include Program BC401_EVE_S1_CARRIER
*--------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*--------------------------------------------------*
CLASS lcl_airplane DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
EXCEPTIONS
wrong_planetype,
display_attributes.
CLASS-METHODS:
display_n_o_airplanes,
class_constructor.
EVENTS:
airplane_created.
PROTECTED SECTION.
CONSTANTS:
c_pos_1 TYPE i VALUE 30.
PRIVATE SECTION.
TYPES:
ty_planetypes TYPE STANDARD TABLE OF saplane
WITH NON-UNIQUE KEY planetype.
DATA:
mv_name
mv_planetype
mv_weight
mv_tankcap
TYPE
TYPE
TYPE
TYPE
string,
saplane-planetype,
saplane-weight,
saplane-tankcap.
CLASS-DATA:
gv_n_o_airplanes TYPE i,
gt_planetypes
TYPE ty_planetypes.
CLASS-METHODS:
get_technical_attributes
IMPORTING
iv_type
TYPE saplane-planetype
EXPORTING
ev_weight
TYPE saplane-weight
ev_tankcap TYPE saplane-tankcap
EXCEPTIONS
wrong_planetype.
ENDCLASS.
"lcl_airplane DEFINITION
*-------------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
© Copyright. All rights reserved.
237
Unit 5: Object-Oriented Events
METHOD class_constructor.
SELECT * FROM saplane INTO TABLE gt_planetypes.
ENDMETHOD.
"class_constructor
METHOD constructor.
mv_name
= iv_name.
mv_planetype
= iv_planetype.
get_technical_attributes(
EXPORTING
iv_type = iv_planetype
IMPORTING
ev_weight = mv_weight
ev_tankcap = mv_tankcap
EXCEPTIONS
wrong_planetype = 1 ).
IF sy-subrc <> 0.
RAISE wrong_planetype.
ELSE.
gv_n_o_airplanes = gv_n_o_airplanes + 1.
RAISE EVENT airplane_created.
ENDIF.
ENDMETHOD.
"constructor
METHOD display_attributes.
...
ENDMETHOD.
"display_attributes
METHOD display_n_o_airplanes.
...
ENDMETHOD.
"display_n_o_airplanes
METHOD get_technical_attributes.
...
ENDMETHOD.
ENDCLASS.
"get_technical_attributes
"lcl_airplane IMPLEMENTATION
*-------------------------------------------*
*
CLASS lcl_cargo_plane DEFINITION
*-------------------------------------------*
CLASS lcl_cargo_plane
DEFINITION INHERITING FROM lcl_airplane.
...
ENDCLASS.
"lcl_cargo_plane DEFINITION
*-----------------------------------------------*
*
CLASS lcl_cargo_plane IMPLEMENTATION
*-----------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
238
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
...
ENDCLASS.
"lcl_cargo_plane IMPLEMENTATION
*------------------------------------------------*
*
CLASS lcl_passenger_plane DEFINITION
*------------------------------------------------*
CLASS lcl_passenger_plane
DEFINITION INHERITING FROM lcl_airplane.
...
ENDCLASS.
"lcl_passenger_plane DEFINITION
*-------------------------------------------------*
*
CLASS lcl_passenger_plane IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
...
ENDCLASS.
"lcl_passenger_plane IMPLEMENTATION
*--------------------------------------------------*
*
CLASS lcl_carrier DEFINITION
*--------------------------------------------------*
CLASS lcl_carrier DEFINITION.
PUBLIC SECTION.
INTERFACES lif_partner.
METHODS:
constructor IMPORTING iv_name TYPE string,
display_attributes.
PRIVATE SECTION.
DATA:
mv_name
TYPE string,
mt_airplanes TYPE TABLE OF REF TO lcl_airplane.
METHODS:
on_airplane_created FOR EVENT airplane_created
OF lcl_airplane
IMPORTING sender,
display_airplanes.
ENDCLASS.
"lcl_carrier DEFINITION
*--------------------------------------------------*
*
CLASS lcl_carrier IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_airplane_created FOR ALL INSTANCES.
ENDMETHOD.
"constructor
METHOD lif_partner~display_partner.
© Copyright. All rights reserved.
239
Unit 5: Object-Oriented Events
display_attributes( ).
ENDMETHOD.
"lif_partners~display_partner
METHOD on_airplane_created.
APPEND sender TO mt_airplanes.
ENDMETHOD.
"on_airplane_created
METHOD display_attributes.
SKIP 2.
WRITE: icon_flight AS ICON,
mv_name.
ULINE.
ULINE.
display_airplanes( ).
ENDMETHOD.
"display_attributes
METHOD display_airplanes.
DATA: lo_plane TYPE REF TO lcl_airplane.
LOOP AT mt_airplanes INTO lo_plane.
lo_plane->display_attributes( ).
ENDLOOP.
ENDMETHOD.
"display_airplanes
ENDCLASS.
"lcl_carrier IMPLEMENTATION
Include Program BC401_EVE_S1_RENTAL
*-----------------------------------------------*
*
CLASS lcl_vehicle DEFINITION
*-----------------------------------------------*
CLASS lcl_vehicle DEFINITION.
PUBLIC SECTION.
METHODS:
constructor IMPORTING iv_make TYPE string,
display_attributes.
CLASS-METHODS:
get_count EXPORTING ev_count TYPE i.
EVENTS:
vehicle_created.
PRIVATE SECTION.
DATA:
mv_make TYPE string.
CLASS-DATA:
gv_n_o_vehicles TYPE i.
ENDCLASS.
"lcl_vehicle DEFINITION
*-------------------------------------------------*
*
CLASS lcl_vehicle IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_vehicle IMPLEMENTATION.
METHOD constructor.
mv_make = iv_make.
ADD 1 TO gv_n_o_vehicles.
RAISE EVENT vehicle_created.
ENDMETHOD.
"constructor
240
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
METHOD display_attributes.
WRITE mv_make.
ENDMETHOD.
"display_attributes
METHOD get_count.
ev_count = gv_n_o_vehicles.
ENDMETHOD.
"get_count
ENDCLASS.
"lcl_vehicle IMPLEMENTATION
*-----------------------------------------------*
*
CLASS lcl_truck DEFINITION
*-----------------------------------------------*
CLASS lcl_truck DEFINITION INHERITING FROM lcl_vehicle.
...
ENDCLASS.
"lcl_truck DEFINITION
*-----------------------------------------------*
*
CLASS lcl_truck IMPLEMENTATION
*-----------------------------------------------*
CLASS lcl_truck IMPLEMENTATION.
...
ENDCLASS.
"lcl_truck DEFINITION
*-------------------------------------------------*
*
CLASS lcl_bus DEFINITION
*-------------------------------------------------*
CLASS lcl_bus DEFINITION INHERITING FROM lcl_vehicle.
...
ENDCLASS.
"lcl_bus DEFINITION
*-------------------------------------------------*
*
CLASS lcl_bus IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_bus IMPLEMENTATION.
...
ENDCLASS.
"lcl_bus DEFINITION
*-------------------------------------------------*
*
CLASS lcl_rental DEFINITION
*--------------------------------------------------*
CLASS lcl_rental DEFINITION.
PUBLIC SECTION.
INTERFACES:
lif_partner.
METHODS:
constructor IMPORTING iv_name TYPE string,
display_attributes.
© Copyright. All rights reserved.
241
Unit 5: Object-Oriented Events
PRIVATE SECTION.
DATA:
mv_name TYPE string,
mt_vehicles TYPE TABLE OF REF TO lcl_vehicle.
METHODS:
on_vehicle_created FOR EVENT vehicle_created
OF lcl_vehicle
IMPORTING sender.
ENDCLASS.
"lcl_rental DEFINITION
*-------------------------------------------------*
*
CLASS lcl_rental IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_rental IMPLEMENTATION.
METHOD lif_partner~display_partner.
display_attributes( ).
ENDMETHOD.
"lif_partners~display_partner
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_vehicle_created FOR ALL INSTANCES.
ENDMETHOD.
"constructor
METHOD on_vehicle_created.
APPEND sender TO mt_vehicles.
ENDMETHOD.
"on_vehicle_created
METHOD display_attributes.
DATA:
lo_vehicle TYPE REF TO lcl_vehicle.
WRITE: / icon_transport_proposal AS ICON,
mv_name.
WRITE: / 'Here comes the vehicle list: '.
ULINE.
ULINE.
LOOP AT mt_vehicles INTO lo_vehicle.
lo_vehicle->display_attributes( ).
ENDLOOP.
ENDMETHOD.
"display_attributes
ENDCLASS.
"lcl_rental IMPLEMENTATION
Main Program SAPBC401_EVE_S1
REPORT
sapbc401_eve_s1.
TYPE-POOLS icon.
INCLUDE bc401_eve_s1_agency.
INCLUDE bc401_eve_s1_carrier.
INCLUDE bc401_eve_s1_rental.
DATA:
go_vehicle
go_truck
go_bus
go_rental
go_agency
242
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
REF
TO
TO
TO
TO
TO
lcl_vehicle,
lcl_truck,
lcl_bus,
lcl_rental,
lcl_travel_agency,
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
go_carrier
go_airplane
go_cargo
go_passenger
gv_count
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
i.
TO
TO
TO
TO
lcl_carrier,
lcl_airplane,
lcl_cargo_plane,
lcl_passenger_plane,
START-OF-SELECTION.
*******************
******* create travel_agency
CREATE OBJECT go_agency
EXPORTING
iv_name = 'Travel&smile Travel'.
******* create rental
CREATE OBJECT go_rental
EXPORTING
iv_name = 'Happy Car Rental'.
***** Insert rental company into partner list
***** of travel agency
go_agency->add_partner( go_rental ).
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'MAN'
iv_cargo = 45.
*
go_rental->add_vehicle( go_truck ).
******* create truck
CREATE OBJECT go_bus
EXPORTING
iv_make
= 'Mercedes'
iv_passengers = 80.
*
go_rental->add_vehicle( go_bus ).
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'VOLVO'
iv_cargo = 48.
*
go_rental->add_vehicle( go_truck ).
***** Create Carrier
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly-Travel'.
***** Insert carrier into business partner list
***** of travel agency
go_agency->add_partner( go_carrier ).
***** Passenger Plane
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
© Copyright. All rights reserved.
243
Unit 5: Object-Oriented Events
*
go_carrier->add_airplane( go_passenger ).
ELSE.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
***** cargo Plane
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc = 0.
*
go_carrier->add_airplane( go_cargo ).
ELSE.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
***** show attributes of all partners travel agency
go_agency->display_attributes( ).
244
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Classes
LESSON SUMMARY
You should now be able to:
●
Implement event-controlled method calls
●
Trigger and handle events
●
Register for events
●
Explain visibility sections in event handling
© Copyright. All rights reserved.
245
Unit 5
Lesson 2
Implementing Events in Local Interfaces
LESSON OVERVIEW
This lesson explains the implementation of events in local interfaces.
Business Example
As a developer, you need to implement events in local classes of the airplane. For this reason,
you require the following knowledge:
●
An understanding of events
●
An understanding of interfaces
●
An understanding of implementing events in local interfaces
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement events in local interfaces
Events in Local Interfaces
Events can be defined as interface components.
Triggering and handling events are done the same way as in classes.
●
The steps to implement event handling for Interfaces are as follows:
1. Define event in an interface.
2. Trigger the interface event in implementing classes.
3. Handle interface event in handler class (client class).
4. Register event handling.
246
© Copyright. All rights reserved.
Unit 5
Exercise 15
Implement Handling of Interface Events
Business Example
Airline and car rental company references are to be entered into the travel agent’s list. This
process is to be event-controlled. Be sure to create your program so that it can be easily
extended to manage additional business partners of the travel agent in the future.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_EVE_S1
Solution: SAPBC401_EVE_S2
Define an event for the creation of a business partner. Trigger and handle the event so that
the reference to the business partner is entered into the travel agent’s list of partners.
1. Use your ZBC401_##_MAIN program or copy the model solution from the previous
exercise.
2. Remove the calls of the method ADD_PARTNER from your main program.
Note:
The entry of a business partner reference into the travel agent’s list is to be
event-controlled.
3. If necessary, examine your UML diagram. Which class or interface defines the event?
Which class or interface triggers it? Which class or interface handles it?
If applicable, illustrate the relationships in your UML diagram.
4. Define the event PARTNER_CREATED and trigger it using a suitable method in all classes
that implement the interface.
5. Remove the method ADD_PARTNER in the class LCL_TRAVEL_AGENCY. Replace it by a
handler method for the event that you just defined (suggested name:
ON_PARTNER_CREATED).
6. Register the new handler method, so that every business partner created was added into
the partner list by the travel agency.
© Copyright. All rights reserved.
247
Unit 5: Object-Oriented Events
Note:
Although this model is unrealistic, we will use it for the time being. A different
rule for entering the business partner can be created later.
7. Observe the execution of the program in the ABAP Debugger.
248
© Copyright. All rights reserved.
Unit 5
Solution 15
Implement Handling of Interface Events
Business Example
Airline and car rental company references are to be entered into the travel agent’s list. This
process is to be event-controlled. Be sure to create your program so that it can be easily
extended to manage additional business partners of the travel agent in the future.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_EVE_S1
Solution: SAPBC401_EVE_S2
Define an event for the creation of a business partner. Trigger and handle the event so that
the reference to the business partner is entered into the travel agent’s list of partners.
1. Use your ZBC401_##_MAIN program or copy the model solution from the previous
exercise.
a) Carry out this step in the usual manner. For more information, refer to the SAP Library.
2. Remove the calls of the method ADD_PARTNER from your main program.
Note:
The entry of a business partner reference into the travel agent’s list is to be
event-controlled.
a) See the source code extract from the model solution.
3. If necessary, examine your UML diagram. Which class or interface defines the event?
Which class or interface triggers it? Which class or interface handles it?
The local interface defines the event.
If applicable, illustrate the relationships in your UML diagram.
a) Speak to your instructor if you have any questions.
4. Define the event PARTNER_CREATED and trigger it using a suitable method in all classes
that implement the interface.
a) See the source code extract from the model solution.
5. Remove the method ADD_PARTNER in the class LCL_TRAVEL_AGENCY. Replace it by a
handler method for the event that you just defined (suggested name:
ON_PARTNER_CREATED).
a) See the source code extract from the model solution.
© Copyright. All rights reserved.
249
Unit 5: Object-Oriented Events
6. Register the new handler method, so that every business partner created was added into
the partner list by the travel agency.
Note:
Although this model is unrealistic, we will use it for the time being. A different
rule for entering the business partner can be created later.
a) See the source code extract from the model solution.
7. Observe the execution of the program in the ABAP Debugger.
a) Carry out this step in the usual manner. Additional information about the ABAP
Debugger is available in the SAP Library.
Solution - Include Program BC401_EVE_S2_AGENCY
*-----------------------------------------------*
* INTERFACE lif_partners
*&----------------------------------------------*
INTERFACE lif_partner.
METHODS:
display_partner.
EVENTS:
partner_created.
ENDINTERFACE.
"lif_partners
*------------------------------------------------*
* CLASS lcl_travel_agency DEFINITION
*------------------------------------------------*
CLASS lcl_travel_agency DEFINITION.
PUBLIC SECTION.
METHODS:
constructor IMPORTING iv_name TYPE string,
display_agency_partners,
display_attributes.
PRIVATE SECTION.
DATA:
mv_name TYPE string,
mt_partners TYPE TABLE OF REF TO lif_partner.
METHODS:
on_partner_created FOR EVENT partner_created
OF lif_partner
IMPORTING sender.
ENDCLASS.
"lcl_travel_agency DEFINITION
*-------------------------------------------------*
* CLASS lcl_travel_agency IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_travel_agency IMPLEMENTATION.
METHOD display_attributes.
WRITE: / icon_private_files AS ICON,
'Travel Agency:'(007), mv_name.
SKIP.
display_agency_partners( ).
ENDMETHOD.
"display_attributes
METHOD display_agency_partners.
250
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Interfaces
DATA:
lo_partner TYPE REF TO lif_partner.
WRITE 'Here are the partners of the travel agency:'(008).
ULINE.
LOOP AT mt_partners INTO lo_partner.
lo_partner->display_partner( ).
ENDLOOP.
ENDMETHOD.
"display_agency_partners
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_partner_created FOR ALL INSTANCES.
ENDMETHOD.
"constructor
METHOD on_partner_created.
APPEND sender TO mt_partners.
ENDMETHOD.
"on_partner_created
ENDCLASS.
"lcl_travel_agency IMPLEMENTATION
Solution - Include Program BC401_EVE_S2_RENTAL
*--------------------------------------------------*
* CLASS lcl_vehicle DEFINITION
*--------------------------------------------------*
CLASS lcl_vehicle DEFINITION.
...
ENDCLASS.
"lcl_vehicle DEFINITION
*--------------------------------------------------*
* CLASS lcl_vehicle IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_vehicle IMPLEMENTATION.
...
ENDCLASS.
"lcl_vehicle IMPLEMENTATION
*--------------------------------------------------*
* CLASS lcl_truck DEFINITION
*--------------------------------------------------*
CLASS lcl_truck DEFINITION INHERITING FROM lcl_vehicle.
...
ENDCLASS.
"lcl_truck DEFINITION
*--------------------------------------------------*
* CLASS lcl_truck IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_truck IMPLEMENTATION.
...
ENDCLASS.
"lcl_truck DEFINITION
*--------------------------------------------------*
* CLASS lcl_bus DEFINITION
*--------------------------------------------------*
CLASS lcl_bus DEFINITION INHERITING FROM lcl_vehicle.
...
ENDCLASS. "lcl_bus DEFINITION
© Copyright. All rights reserved.
251
Unit 5: Object-Oriented Events
*--------------------------------------------------*
* CLASS lcl_bus IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_bus IMPLEMENTATION.
...
ENDCLASS. "lcl_bus DEFINITION
*--------------------------------------------------*
* CLASS lcl_rental DEFINITION
*--------------------------------------------------*
CLASS lcl_rental DEFINITION.
...
ENDCLASS. "lcl_rental DEFINITION
*--------------------------------------------------*
* CLASS lcl_rental IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_rental IMPLEMENTATION.
METHOD lif_partner~display_partner.
display_attributes( ).
ENDMETHOD. "lif_partners~display_partner
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_vehicle_created FOR ALL INSTANCES.
RAISE EVENT lif_partner~partner_created.
ENDMETHOD.
"constructor
METHOD on_vehicle_created.
APPEND sender TO mt_vehicles.
ENDMETHOD.
"on_vehicle_created
METHOD display_attributes.
...
ENDMETHOD. "display_attributes
ENDCLASS.
"lcl_rental IMPLEMENTATION
Solution - Include Program BC401_EVE_S2_CARRIER
*-------------------------------------------------*
* CLASS lcl_airplane DEFINITION
*-------------------------------------------------*
CLASS lcl_airplane DEFINITION.
...
ENDCLASS. "lcl_airplane DEFINITION
*-------------------------------------------------*
* CLASS lcl_airplane IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
...
ENDCLASS. "lcl_airplane IMPLEMENTATION
*-------------------------------------------------*
252
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Interfaces
* CLASS lcl_cargo_plane DEFINITION
*-------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING
FROM lcl_airplane.
...
ENDCLASS. "lcl_cargo_plane DEFINITION
*-------------------------------------------------*
* CLASS lcl_cargo_plane IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
...
ENDCLASS. "lcl_cargo_plane IMPLEMENTATION
*-------------------------------------------------*
* CLASS lcl_passenger_plane DEFINITION
*-------------------------------------------------*
CLASS lcl_passenger_plane DEFINITION INHERITING
FROM lcl_airplane.
...
ENDCLASS. "lcl_passenger_plane DEFINITION
*-------------------------------------------------*
* CLASS lcl_passenger_plane IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
...
ENDCLASS. "lcl_passenger_plane IMPLEMENTATION
*-------------------------------------------------*
* CLASS lcl_carrier DEFINITION
*-------------------------------------------------*
CLASS lcl_carrier DEFINITION.
...
ENDCLASS. "lcl_carrier DEFINITION
*-------------------------------------------------*
* CLASS lcl_carrier IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_airplane_created FOR ALL INSTANCES.
RAISE EVENT lif_partner~partner_created.
ENDMETHOD.
"constructor
METHOD lif_partner~display_partner.
display_attributes( ).
ENDMETHOD.
"lif_partners~display_partner
METHOD on_airplane_created.
APPEND sender TO mt_airplanes.
ENDMETHOD. "on_airplane_created
METHOD display_attributes.
...
ENDMETHOD. "display_attributes
METHOD display_airplanes.
...
ENDMETHOD. "display_airplanes
ENDCLASS.
© Copyright. All rights reserved.
"lcl_carrier IMPLEMENTATION
253
Unit 5: Object-Oriented Events
Solution - Main Program SAPBC401_EVE_S2
REPORT sapbc401_eve_s2.
TYPE-POOLS icon.
INCLUDE bc401_eve_s2_agency.
INCLUDE bc401_eve_s2_carrier.
INCLUDE bc401_eve_s2_rental.
DATA:
go_vehicle TYPE REF TO lcl_vehicle,
go_truck TYPE REF TO lcl_truck,
go_bus TYPE REF TO lcl_bus,
go_rental TYPE REF TO lcl_rental,
go_passenger TYPE REF TO lcl_passenger_plane,
go_cargo TYPE REF TO lcl_cargo_plane,
go_carrier TYPE REF TO lcl_carrier,
go_agency TYPE REF TO lcl_travel_agency.
START-OF-SELECTION.
*******************
******* create travel_agency
CREATE OBJECT go_agency
EXPORTING
iv_name = 'Travel&Smile Travel'.
******* create rental
CREATE OBJECT go_rental
EXPORTING
iv_name = 'Happy Car Rental'.
* go_agency->add_partner( go_rental ).
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'MAN'
iv_cargo = 45.
******* create truck
CREATE OBJECT go_bus
EXPORTING
iv_name
= 'Mercedes'
iv_passengers = 80.
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'VOLVO'
iv_cargo = 48.
***** Create Carrier
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly-Travel'.
* go_agency->add_partner( go_rental ).
254
© Copyright. All rights reserved.
Lesson: Implementing Events in Local Interfaces
***** Passenger Plane
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
***** cargo Plane
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
******* show attributes of all partners of travel_agency
go_agency->display_attributes( ).
© Copyright. All rights reserved.
255
Unit 5: Object-Oriented Events
LESSON SUMMARY
You should now be able to:
●
256
Implement events in local interfaces
© Copyright. All rights reserved.
Unit 5
Learning Assessment
1. Which of the following cannot be defined as interface components?
Choose the correct answer.
X
A Attributes
X
B Methods
X
C Events
X
D Classes
2. Which of the following statements is used to trigger events?
Choose the correct answer.
X
A CLASS-EVENTS
X
B RAISE EVENT
X
C EVENTS
X
D FOR EVENTS
3. You can trigger static events only in static methods.
Determine whether this statement is true or false.
X
True
X
False
4. Which of the following is specified by the definition of the handler method?
Choose the correct answer.
X
A Which method will react to which event of which class
X
B Which instances will perform the reaction
© Copyright. All rights reserved.
257
Unit 5: Learning Assessment
5. Handler methods are registered using the SET HANDLER statement. Registration is only
active at program runtime.
Determine whether this statement is true or false.
X
True
X
False
6. Which visibility section would an event need to be defined in, to ensure that it can only be
handled in the class itself and its subclasses?
Choose the correct answer.
258
X
A Public
X
B Protected
X
C Private
© Copyright. All rights reserved.
Unit 5
Learning Assessment - Answers
1. Which of the following cannot be defined as interface components?
Choose the correct answer.
X
A Attributes
X
B Methods
X
C Events
X
D Classes
2. Which of the following statements is used to trigger events?
Choose the correct answer.
X
A CLASS-EVENTS
X
B RAISE EVENT
X
C EVENTS
X
D FOR EVENTS
3. You can trigger static events only in static methods.
Determine whether this statement is true or false.
X
True
X
False
4. Which of the following is specified by the definition of the handler method?
Choose the correct answer.
X
A Which method will react to which event of which class
X
B Which instances will perform the reaction
© Copyright. All rights reserved.
259
Unit 5: Learning Assessment - Answers
5. Handler methods are registered using the SET HANDLER statement. Registration is only
active at program runtime.
Determine whether this statement is true or false.
X
True
X
False
6. Which visibility section would an event need to be defined in, to ensure that it can only be
handled in the class itself and its subclasses?
Choose the correct answer.
260
X
A Public
X
B Protected
X
C Private
© Copyright. All rights reserved.
UNIT 6
Object-Oriented Repository
Objects
Lesson 1
Creating Global Classes
Exercise 16: Implement a Global Class
262
273
Lesson 2
Defining and Implementing Global Interfaces
Exercise 17: Import and Implement a Global Interface
283
287
Lesson 3
Implementing Inheritance in Global Classes
298
UNIT OBJECTIVES
●
Create global classes
●
Test global classes
●
Use global classes
●
Define and implement global interfaces
●
Import local classes and interfaces
●
Generate UML diagrams for global classes
●
Implement inheritance in global classes
●
Change the display of components in global classes
© Copyright. All rights reserved.
261
Unit 6
Lesson 1
Creating Global Classes
LESSON OVERVIEW
This lesson explains how to create global classes.
Business Example
As a developer, you must create a global ABAP class for airplanes that can be accessed by all
other ABAP Objects in the SAP system. For this reason, you require the following knowledge:
●
An understanding of global classes
●
An understanding of how to test and use global classes
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Create global classes
●
Test global classes
●
Use global classes
Definition of Global Classes
Note:
A large number of figures are used in the lesson. Note that the appearance of
some of the icons or menus depends on the release level.
As with subroutines, use local classes or interfaces only within the program in which they are
defined and implemented. The CLASS statement is a local declarative statement in the
program. As the TYPES statement defines local data types, the CLASS statement defines
local object types.
On the other hand, global classes or global interfaces are individual repository objects with all
the standard ABAP Workbench features such as active integration, versioning, transport
system. The namespace convention, for example Y*, Z*, or a special customer namespace is
the same as that name used for the namespace of other repository objects.
Therefore, a special maintenance tool is available in the ABAP Workbench, which is the Class
Builder.
If you are unsure about a certain feature in the Class Builder, you are advised to use the
Quickinfo. It is the explanatory text that appears when you place the cursor over an icon and
leave it there for a short time.
262
© Copyright. All rights reserved.
Lesson: Creating Global Classes
Creating Global Classes in the Object Navigator
Figure 104: Creating Global Classes in the Object Navigator
As with other repository objects, the separate navigation area of the Object Navigator makes
it the ideal development tool for all repository objects. The easiest way to create a new global
class is to use the context menu in the navigation area. To do so, first select the package node
or select the class node within a package.
A dialog box appears that offers you some choices for the new class. Select Usual ABAP class.
The global class or global interface is then displayed in the Class Builder table in the editor
area of the Object Navigator.
© Copyright. All rights reserved.
263
Unit 6: Object-Oriented Repository Objects
Definition of Attributes in a Global Class
Figure 105: Definition of Attributes
Choose the Attributes tab page to open a list of all attribute definitions in the class. You can
also define new attributes here.
You can use the input help when defining the types of attributes. Remember to use
meaningful short descriptions.
264
© Copyright. All rights reserved.
Lesson: Creating Global Classes
Create Methods in Global Class
Figure 106: Definition of Methods
Choose the Methods tab page to open a list of all method definitions in the class. You can
define new methods here. Remember to use meaningful short descriptions.
There are separate editor windows for the method parameters (also known as method
signature) and the implementation.
Choose the Constructor button to define an instance constructor. The system automatically
chooses the name of constructor.
Hint:
Methods can be transported separately because each implementation is stored
in an own ABAP include.
© Copyright. All rights reserved.
265
Unit 6: Object-Oriented Repository Objects
Definition of Method Parameters
Figure 107: Definition of Method Signatures
In the method list, select a method and choose the Parameter button to go to the signature
maintenance. You can define new formal parameters here. You can use the input help when
defining the type of the parameters. Remember to use meaningful short descriptions.
You can browse between the signatures with the help of the Previous Methodor Next Methods
button. Choose the Methods button to return to the method list.
Implementation of Methods
Figure 108: Implementation of Methods
266
© Copyright. All rights reserved.
Lesson: Creating Global Classes
In the method list, select a method by double-clicking it. Alternatively, choose the Source code
button to go to the source text maintenance if a method is already selected. You can
implement the methods here.
Hint:
Choose the relevant button to display the method’s signature.
Displaying the Method Definition
Figure 109: Displaying the Method Definition
Choose Goto → Method definition to change the attributes of your method during
implementation. Optionally, you can define an event handler method on the Attributes tab
page in the dialog box.
© Copyright. All rights reserved.
267
Unit 6: Object-Oriented Repository Objects
Definition of Components Using the Navigation Area
Figure 110: Definition of Components Using the Navigation Area
You can define attributes, methods, or events in the context menu of the Object Navigator’s
navigation area. The properties are then maintained in a dialog box, and not in the table.
Hint:
Choose Class → Print or Method → Print to print selected portions of the source
text.
268
© Copyright. All rights reserved.
Lesson: Creating Global Classes
Class Builder Testing Environment
Figure 111: The Class Builder Testing Environment
You can test active global classes by choosing menu path Class → Run → In Test
Environment, choosing the corresponding application toolbar button, or press F8.
Static attributes and static methods are directly accessible in the test environment. Instance
attributes and instance methods are accessible after instance creation only. You can create
an instance using the Create Instance button.
The system only lists the public components. Methods can be tested using the Execute
Method button.
The following are the steps to trigger events in a class:
1. Select an event.
2. Choose Handler to register a standard method for the event.
3. Call a method in which the event trigger was implemented.
The event that was triggered and all of the exported actual parameters are displayed in a list.
© Copyright. All rights reserved.
269
Unit 6: Object-Oriented Repository Objects
Use of Global Classes in the ABAP Editor
Figure 112: Separation of Navigation and Editing Areas in the Object Navigator
Like other repository objects, global classes, and interfaces are added in the navigation area
of the object navigator. This way, the discussed advantages also apply to global classes and
interfaces.
Object Instantiation Using Drag and Drop
Figure 113: Object Instantiation Using Drag and Drop
In the navigation area, select a class name and move it to the editing area. This action creates
a CREATE OBJECT statement. Then, add the reference variable and the actual parameters, if
applicable, to the statement.
270
© Copyright. All rights reserved.
Lesson: Creating Global Classes
Alternatively, you can also choose the Pattern button. You can find the CREATE OBJECT
statement by selecting ABAP Objects Patterns. You can generate the statement using the
input help.
Method Calls Using Drag and Drop
Figure 114: Method Calls Using Drag and Drop
In the navigation area, select a method name and move it to the editing area. This action
creates a CREATE METHOD statement. Then, add the reference variable and the actual
parameters, if applicable, to the statement.
Alternatively, you can also choose the Pattern button. The CALL METHOD statement is under
ABAP Objects Pattern. You can generate the statement using the input help.
Note:
To generate patterns, enable the modern functional writing style for method calls.
Choose Utilities → Settings → Pattern and select the Functional Writing Style for
Call Method checkbox.
© Copyright. All rights reserved.
271
Unit 6: Object-Oriented Repository Objects
272
© Copyright. All rights reserved.
Unit 6
Exercise 16
Implement a Global Class
Business Example
You want to create a global class to represent hotels.
Note:
This exercise uses the main program ZBC401_##_MAIN completed in the
previous exercise. If not completed, copy the model solution with its INCLUDES
from the previous exercise. In the exercises for this course, when the input values
include ##, replace ## with your group number.
Template: SAPBC401_EVE_S2 (main program)
.
Solutions:
●
SAPBC401_GCL_S1 (main program)
●
CL_HOTEL (global class)
Create a Global Class
Create a global class for hotels.
1. Create the global class ZCL_##_HOTEL (## is your two-digit group number).
2. Define a private constant named C_POS_1 of type I, with the value 30.
3. Define a private instance attribute named MV_NAME, or type STRING.
4. Define a private instance attribute named MV_BEDS, of type I.
5. Define a private static attribute named GV_N_O_HOTELS, of type I.
6. Define the following methods in the class:
Table 4: Methods
Method Name
Method Characteristics
CONSTRUCTOR
Instance constructor for setting the private
attributes with the import parameters
IV_NAME and IV_BEDS, and to increment
the counter GV_N_O_HOTELS
DISPLAY_ATTRIBUTES
Public instance method for displaying the
attributes
© Copyright. All rights reserved.
273
Unit 6: Object-Oriented Repository Objects
Method Name
Method Characteristics
DISPLAY_N_O_HOTELS
Public static method to display the number
of created hotel instances
Test the Class
Check your work.
1. Save, check, and activate your class.
2. Test your class in the Class Builder testing environment.
Use the Hotel Class in Your Program
Create an instance of your global class for hotels in your main program.
1. Define a reference variable, specify your global hotel class as the type, and create an
instance.
2. If you have not done the optional exercise, where you add business partners to the travel
agency through event handling, try to call method ADD_PARTNER for the hotel.
3. Why can the hotel not yet be integrated into the list of travel agency business partners?
4. Could the local interface LIF_PARTNER be implemented in the global class for hotels?
274
© Copyright. All rights reserved.
Unit 6
Solution 16
Implement a Global Class
Business Example
You want to create a global class to represent hotels.
Note:
This exercise uses the main program ZBC401_##_MAIN completed in the
previous exercise. If not completed, copy the model solution with its INCLUDES
from the previous exercise. In the exercises for this course, when the input values
include ##, replace ## with your group number.
Template: SAPBC401_EVE_S2 (main program)
.
Solutions:
●
SAPBC401_GCL_S1 (main program)
●
CL_HOTEL (global class)
Create a Global Class
Create a global class for hotels.
1. Create the global class ZCL_##_HOTEL (## is your two-digit group number).
a) In transaction SE80, in the unnamed dropdown list on the left of the screen, choose
Class/ Interface and specify the name of the new global class, ZCL_##_HOTEL.
b) Press Enter.
A Create Class/Interfacedialog box appears
c) To create the class, choose Yes.
d) In the Create Class ZCL_##_HOTELdialog box, enter a short description for the global
class and choose Save.
e) In the Create Object Directory Entrydialog box, enter your package name and choose
Save.
The Prompt for transportable Workbench requestdialog box displays.
f) In the Prompt for transportable Workbench requestdialog box, enter the request name
supplied by your instructor. Choose Continue.
2. Define a private constant named C_POS_1 of type I, with the value 30.
a) Choose the Attributes tab.
b) In the attribute field, enter C_POS_1.
c) In the Level field, use the input help to choose Constant.
© Copyright. All rights reserved.
275
Unit 6: Object-Oriented Repository Objects
d) In the Visibility field, use the input help to choose Private.
e) In the Associated Type field, enter I.
f) In the Description field, enter Output Position.
g) In the Initial Value field, enter 30.
3. Define a private instance attribute named MV_NAME, or type STRING.
a) In the Attribute field, enter MV_NAME.
b) In the Level field, use the input help to choose Instance Attribute.
c) In the Visibility field, use the input help to choose Private.
d) In the Associated Type field, enter STRING.
e) In the Description field, enter Hotel Name.
4. Define a private instance attribute named MV_BEDS, of type I.
a) In the Attribute field, enter MV_BEDS.
b) In the Level field, use the input help to choose Instance Attribute.
c) In the Visibility field, use the value input help to choose Private.
d) In the Associated Type field, enter I.
e) In the Description field, enter Number of Beds.
5. Define a private static attribute named GV_N_O_HOTELS, of type I.
a) In the Attribute field, enter GV_N_O_HOTELS.
b) In the Level field, use the input help to choose Static Attribute.
c) In the Visibility field, use the input help to choose Private.
d) In the Associated Type field, enter I.
e) In the Description field, enter Number of Hotels.
6. Define the following methods in the class:
Table 4: Methods
Method Name
Method Characteristics
CONSTRUCTOR
Instance constructor for setting the private
attributes with the import parameters
IV_NAME and IV_BEDS, and to increment
the counter GV_N_O_HOTELS
DISPLAY_ATTRIBUTES
Public instance method for displaying the
attributes
DISPLAY_N_O_HOTELS
Public static method to display the number
of created hotel instances
a) Choose the Methods tab.
276
© Copyright. All rights reserved.
Lesson: Creating Global Classes
b) Choose the Create Constructorbutton on the application toolbar.
c) Put your cursor on method CONSTRUCTOR and choose the Parameter button.
d) In the Parameter field, enter IV_NAME.
e) In the Associated Type field, enter STRING.
f) In the Parameter field, enter IV_BEDS.
g) In the Associated Type field, enter I.
h) Choose the Back to Methods button.
i) Put your cursor in the Method field under CONSTRUCTOR and enter
DISPLAY_ATTRIBUTES.
j) In the Level field, use the value selector to choose Instance Method.
k) In the Visibility field, use the value selector to choose Public.
l) In the Method field under DISPLAY_ATTRIBUTES, enter DISPLAY_N_O_HOTELS.
m) In the Level field, use the value selector to choose Static Method.
n) In the Visibility field, use the value selector to choose Public.
o) Double-click the CONSTRUCTOR method. Choose Yes to save the class. Enter the
code from the model solution.
p) Choose Save, then Back.
q) Double-click the DISPLAY_ATTRIBUTESmethod. Choose Yes to save the class. Enter
the code from the model solution.
r) Choose Save, then Back.
s) Double-click the DISPLAY_N_O_HOTELSmethod. Choose Yes to save the class. Enter
the code from the model solution.
t) Choose Save, and choose Back.
Test the Class
Check your work.
1. Save, check, and activate your class.
a) Save your class.
b) To check your class, on the application toolbar, choose the Check button.
c) To activate your class, on the application toolbar, choose the Activate button.
2. Test your class in the Class Builder testing environment.
a) To test your class, press F8.
All methods which can be tested will be displayed. At first only the
DISPLAY_N_O_HOTELS will be listed, since all other methods are instance methods.
b) To test this method, choose the Execute button next to DISPLAY_N_O_HOTELS.
c) Choose the Create Instance button on the toolbar.
© Copyright. All rights reserved.
277
Unit 6: Object-Oriented Repository Objects
The parameters of the instance constructor will be displayed.
d) Choose the Edit Long Field of Structurebutton next to IV_NAME, and enter a test
name. Choose Back.
e) Enter a number for the parameter IV_BEDS.
f) Choose the Create Instance button.
Now that the test object has been created, the method DISPLAY_ATTRIBUTES is
displayed in the test environment, along with method DISPLAY_N_O_HOTELS.
g) Choose the Execute button for method DISPLAY_ATTRIBUTES, and verify the output.
Use the Hotel Class in Your Program
Create an instance of your global class for hotels in your main program.
1. Define a reference variable, specify your global hotel class as the type, and create an
instance.
a) See source text excerpt from the model solution.
2. If you have not done the optional exercise, where you add business partners to the travel
agency through event handling, try to call method ADD_PARTNER for the hotel.
a) Perform in the same way as for the carrier and the car rental company.
3. Why can the hotel not yet be integrated into the list of travel agency business partners?
The global class for hotels does not implement the interface that is used by the travel
agency class.
4. Could the local interface LIF_PARTNER be implemented in the global class for hotels?
No, global classes can only implement global interfaces. Therefore, the local interface
must be replaced with a global one. This is performed in the next exercise.
a) Model solution as follows:
Solution: Main Program SAPBC401_GCL_S1
REPORT
sapbc401_gcl_s1.
TYPE-POOLS icon.
INCLUDE bc401_gcl_s1_agency.
INCLUDE bc401_gcl_s1_carrier.
INCLUDE bc401_gcl_s1_rental.
DATA:
go_hotel
go_vehicle
go_truck
go_bus
go_rental
go_passenger
go_cargo
go_carrier
go_agency
278
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
REF
REF
REF
REF
REF
TO
TO
TO
TO
TO
TO
TO
TO
TO
cl_hotel,
lcl_vehicle,
lcl_truck,
lcl_bus,
lcl_rental,
lcl_passenger_plane,
lcl_cargo_plane,
lcl_carrier,
lcl_travel_agency.
© Copyright. All rights reserved.
Lesson: Creating Global Classes
START-OF-SELECTION.
*******************
******* create travel_agency
CREATE OBJECT go_agency
EXPORTING
iv_name = 'Travel&Smile Travel'.
******* create hotel
CREATE OBJECT go_hotel
EXPORTING
iv_name = 'Sleep Well Hotel'
iv_beds = 345.
* hotel not added to partner list * does not implement interface
* go_agency->add_partner( go_hotel )
******* create rental
CREATE OBJECT go_rental
EXPORTING
iv_name = 'Happy Car Rental'.
* go_agency->add_partner( go_rental ).
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'MAN'
iv_cargo = 45.
******* create truck
CREATE OBJECT go_bus
EXPORTING
iv_make
= 'Mercedes'
iv_passengers = 80.
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'VOLVO'
iv_cargo = 48.
***** Create Carrier
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly-Travel'.
* go_agency->add_partner( go_rental ).
***** Passenger Plane
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
© Copyright. All rights reserved.
279
Unit 6: Object-Oriented Repository Objects
***** cargo Plane
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
***** show attributes of all partners of travel_agency
go_agency->display_attributes( ).
*****DEFINITION & IMPLEMENTATION of class CL_HOTEL
class CL_HOTEL definition
public
create public .
public section.
*"* public components of class CL_HOTEL
*"* do not include other source files here!!!
methods CONSTRUCTOR
importing
!IV_NAME type STRING
!IV_BEDS type I .
methods DISPLAY_ATTRIBUTES .
class-methods DISPLAY_N_O_HOTELS .
protected section.
*"* protected components of class CL_HOTEL
*"* do not include other source files here!!!
private section.
*"* private components of class CL_HOTEL
*"* do not include other source files here!!!
data MV_NAME type STRING .
class-data GV_N_O_HOTELS type I .
data MV_BEDS type I .
constants C_POS_1 type I value 30. "#EC NOTEXT
ENDCLASS.
CLASS CL_HOTEL IMPLEMENTATION.
***** Instance Public Method CL_HOTEL->CONSTRUCTOR
METHOD constructor .
mv_name = iv_name.
mv_beds = iv_beds.
ADD 1 TO gv_n_o_hotels.
ENDMETHOD.
***** Instance Public Method CL_HOTEL->DISPLAY_ATTRIBUTES
METHOD display_attributes .
WRITE:
/ 'Hotel'(001),
280
AT c_pos_1 mv_name,
© Copyright. All rights reserved.
Lesson: Creating Global Classes
/ 'Total number of beds:'(002), AT c_pos_1 mv_beds.
ULINE.
ULINE.
SKIP.
ENDMETHOD.
***** Static Public Method CL_HOTEL=>DISPLAY_N_O_HOTELS
METHOD display_n_o_hotels.
WRITE:
/ 'Total number of hotels:'(003), gv_n_o_hotels.
ENDMETHOD.
ENDCLASS.
© Copyright. All rights reserved.
281
Unit 6: Object-Oriented Repository Objects
LESSON SUMMARY
You should now be able to:
282
●
Create global classes
●
Test global classes
●
Use global classes
© Copyright. All rights reserved.
Unit 6
Lesson 2
Defining and Implementing Global Interfaces
LESSON OVERVIEW
This lesson explains how to define and implement global interfaces.
Business Example
As a developer, you need to create a global interface so that other developers in your
organization can use the same interface and implement it in their own ways in their classes.
For this reason, you require the following knowledge:
●
An understanding of how to define and implement global interfaces
●
An understanding of how to import local classes and interfaces
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Define and implement global interfaces
●
Import local classes and interfaces
© Copyright. All rights reserved.
283
Unit 6: Object-Oriented Repository Objects
Definition of Global Interfaces
Figure 115: Defining Global Interfaces
You create global interfaces like you create global classes. Right-click the program name in
the Object Name screen area, and choose Create → Class. The naming convention is IF_ for
SAP interfaces and ZIF_ or YIF_ for user-defined interfaces.
284
© Copyright. All rights reserved.
Lesson: Defining and Implementing Global Interfaces
Implementation of Global Interfaces
Figure 116: Including Global Interfaces
If you want to include a global interface in your global class, you must enter the name of the
interface on the Interfaces tab page.
Once you have done that, all of the interface’s components automatically appear on the
relevant tab pages according to the naming convention with the interface resolution operator.
In the example, the global interface ZIF_00_PARTNER containing the method
DISPLAY_PARTNER is incorporated. Double-click the method name to implement the
method.
© Copyright. All rights reserved.
285
Unit 6: Object-Oriented Repository Objects
Import of Local Classes and Interfaces
Figure 117: Importing a Local Program Class
The following procedure is an easy way to make global copies of local classes and local
interfaces.
Hint:
The function to copy local classes to global classes cannot be used from within
OBJECT-NAVIGATOR.
To Import Local Classes and Interfaces
1. On the SAP Easy Access screen, choose Tools → ABAP
Workbench → Development → Class Builder or call transaction SE24.
2. On the Class Builder: Initial Screen, choose Object type → Import → Local classes in
program.
3. In the Import from Programdialog box, enter the name of the main program and, if the
local classes and interfaces were defined within include programs, select the Explode
INCLUDEs checkbox.
4. Choose the Display Classes/Interfacesbutton.
5. Enter names for the global classes and interfaces that you want to create.
6. If applicable, remember the customer namespace.
7. To select all the global names, choose the Select All button.
8. Choose the global classes and interfaces that you want to create and choose the Import
button.
286
© Copyright. All rights reserved.
Unit 6
Exercise 17
Import and Implement a Global Interface
Business Example
Add a hotel as a new business partner in your program for managing a travel agency’s
business partners.
Note:
This exercise uses the main program ZBC401_##_MAIN and the global class
ZCL_##_HOTEL completed in the previous exercises. If not complete, copy the
model solution from the previous exercise and the global class. In the exercises for
this course, when the input values include ##, replace ## with your group
number.
Templates:
●
SAPBC401_GCL_S1 (program)
●
CL_HOTEL (global class)
Solutions:
●
SAPBC401_GCL_S2 (program)
●
CL_HOTEL2 (global class)
●
IF_PARTNER (global interface)
Create Global Interface
Create a global interface for generalized access to business partner instances.
1. If applicable, change the interface name in your UML diagram to ZIF_##_PARTNERS.
2. Create the global interface ZIF_##_PARTNER.
3. Define the instance method DISPLAY_PARTNER in your global interface. If you defined the
event PARTNER_CREATED in your local interface in earlier exercises, also define this
event in your global interface.
Hint:
Instead of creating the global interface manually you can import the local
interface from your program ZBC401_##_MAIN or the template program.
Use the Global Interface in Your Application
In the main program, replace the use of the local interface with the new global interface.
1. Completely remove the definition of the local interface.
© Copyright. All rights reserved.
287
Unit 6: Object-Oriented Repository Objects
2. Adapt all places where the local interface was used so that the global interface is used and
implemented instead.
Hint:
Use the Find/Replace function of the ABAP Editor to reduce the typing
efforts.
Use the Global Interface in the Hotel Class
Edit your hotel class to implement the interface, and then retest your program.
1. Ensure that your main program instantiates your own class ZCL_##_HOTEL and not the
template class.
2. If necessary, add the class ZCL_##_HOTEL to your UML diagram. The class
ZCL_##_HOTEL implements the interface method DISPLAY_PARTNER and triggers the
instance event PARTNER_CREATED. Draw the relationships in your diagram.
3. Declare the interface as an implemented interface in your hotel class.
4. Implement the interface method in such a way that the hotel’s DISPLAY_ATTRIBUTES
instance method is called.
5. Check whether the interface contains an event. If it does, ensure that it is raised in the
constructor of class ZCL_##_HOTEL.
6. Save, check, and activate the global class and main program.
7. Run your program. If you have done everything correctly, the hotel attributes now appear
in the list. If the hotel attributes do not appear in the list, or if an error occurs, use the
ABAP Debugger to analyze the source of the error.
288
© Copyright. All rights reserved.
Unit 6
Solution 17
Import and Implement a Global Interface
Business Example
Add a hotel as a new business partner in your program for managing a travel agency’s
business partners.
Note:
This exercise uses the main program ZBC401_##_MAIN and the global class
ZCL_##_HOTEL completed in the previous exercises. If not complete, copy the
model solution from the previous exercise and the global class. In the exercises for
this course, when the input values include ##, replace ## with your group
number.
Templates:
●
SAPBC401_GCL_S1 (program)
●
CL_HOTEL (global class)
Solutions:
●
SAPBC401_GCL_S2 (program)
●
CL_HOTEL2 (global class)
●
IF_PARTNER (global interface)
Create Global Interface
Create a global interface for generalized access to business partner instances.
1. If applicable, change the interface name in your UML diagram to ZIF_##_PARTNERS.
a) Speak to your instructor if you have any questions.
2. Create the global interface ZIF_##_PARTNER.
a) In transaction SE80, in the unnamed dropdown list on the left of the screen, choose
Class /Interface, specify the name of the interface ZIF_##_PARTNER, and press Enter.
A Create Class/Interfacedialog box displays.
b) To create the interface, choose Yes.
A Create Interface dialog box displays.
c) In the Create Interface dialog box, enter a short description for the interface and
choose Save.
A Create Object Directory Entrydialog box displays.
© Copyright. All rights reserved.
289
Unit 6: Object-Oriented Repository Objects
d) In the Create Object Directory Entrydialog box, enter your package name and choose
Save.
A Prompt for transportable Workbench requestdialog box displays.
e) In the Prompt for transportable Workbench requestdialog box, accept the defaults and
choose Continue.
3. Define the instance method DISPLAY_PARTNER in your global interface. If you defined the
event PARTNER_CREATED in your local interface in earlier exercises, also define this
event in your global interface.
a) Choose the Methods tab.
b) Enter DISPLAY_PARTNER in the Method column.
c) In the Level column, use the input help to choose Instance method.
d) Enter a suitable description.
e) Choose the Events tab.
f) In the Event column, enter PARTNER_CREATED.
g) In the Level column, use the input help to choose Instance event.
h) To activate the interface, choose the Activate button.
Hint:
Instead of creating the global interface manually you can import the local
interface from your program ZBC401_##_MAIN or the template program.
Use the Global Interface in Your Application
In the main program, replace the use of the local interface with the new global interface.
1. Completely remove the definition of the local interface.
a) See source text excerpt from the model solution.
2. Adapt all places where the local interface was used so that the global interface is used and
implemented instead.
Hint:
Use the Find/Replace function of the ABAP Editor to reduce the typing
efforts.
a) See source text excerpt from the model solution.
Use the Global Interface in the Hotel Class
Edit your hotel class to implement the interface, and then retest your program.
1. Ensure that your main program instantiates your own class ZCL_##_HOTEL and not the
template class.
a) See source text excerpt from the model solution.
290
© Copyright. All rights reserved.
Lesson: Defining and Implementing Global Interfaces
2. If necessary, add the class ZCL_##_HOTEL to your UML diagram. The class
ZCL_##_HOTEL implements the interface method DISPLAY_PARTNER and triggers the
instance event PARTNER_CREATED. Draw the relationships in your diagram.
a) Speak to your instructor if you have any questions.
3. Declare the interface as an implemented interface in your hotel class.
a) On the Interfaces tab page in your hotel class, in the Interface field, enter the name of
your interface. Choose Save.
4. Implement the interface method in such a way that the hotel’s DISPLAY_ATTRIBUTES
instance method is called.
a) Choose the Methods tab.
You see the ZIF_##_PARTNER~DISPLAY_PARTNER METHOD.
b) Double-click the ZIF_##_PARTNER~DISPLAY_PARTNER method and enter the
following code:
me->DISPLAY_ATTRIBUTES( ).
5. Check whether the interface contains an event. If it does, ensure that it is raised in the
constructor of class ZCL_##_HOTEL.
a) At the end of the CONSTRUCTOR method, add the following code:
RAISE EVENT ZIF_##_PARTNER~DISPLAY_PARTNER.
6. Save, check, and activate the global class and main program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
7. Run your program. If you have done everything correctly, the hotel attributes now appear
in the list. If the hotel attributes do not appear in the list, or if an error occurs, use the
ABAP Debugger to analyze the source of the error.
a) To run your program, on the application toolbar, choose the Direct Processingbutton.
b) If the list does not display the hotel attributes, or an error occurs, run the ABAP
Debugger.
c) To activate the ABAP Debugger, choose Program → Execute → Debugging.
d) Choose Execute, or press F8.
The ABAP Debugger starts.
Include: BC401_GCL_S2_AGENCY
Hint:
When working with this solution source code please keep in mind that you
have to use your own global class ZCL_##_HOTEL and your own global
interface ZIF_##_PARTNER (instead of CL_HOTEL2 and IF_PARTNER).
*------------------------------------------------*
*
INTERFACE lif_partners
© Copyright. All rights reserved.
291
Unit 6: Object-Oriented Repository Objects
*------------------------------------------------*
*INTERFACE lif_partner.
* METHODS:
*
display_partner.
* EVENTS:
*
partner_created.
*ENDINTERFACE.
"lif_partners
*------------------------------------------------*
*
CLASS lcl_travel_agency DEFINITION
*------------------------------------------------*
CLASS lcl_travel_agency DEFINITION.
PUBLIC SECTION.
METHODS:
constructor IMPORTING iv_name TYPE string,
display_agency_partners,
display_attributes.
PRIVATE SECTION.
DATA:
mv_name
TYPE string,
mt_partners TYPE TABLE OF REF TO if_partner.
METHODS:
on_partner_created FOR EVENT partner_created
OF if_partner
IMPORTING sender.
ENDCLASS.
"lcl_travel_agency DEFINITION
*------------------------------------------------*
*
CLASS lcl_travel_agency IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_travel_agency IMPLEMENTATION.
METHOD display_attributes.
WRITE: / icon_private_files AS ICON,
'Travel Agency:'(007), mv_name.
SKIP.
display_agency_partners( ).
ENDMETHOD.
"display_attributes
METHOD display_agency_partners.
DATA:
lo_partner TYPE REF TO if_partner.
WRITE 'Here are the partners of the travel agency:'(008).
ULINE.
LOOP AT mt_partners INTO lo_partner.
lo_partner->display_partner( ).
ENDLOOP.
ENDMETHOD.
"display_agency_partners
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_partner_created FOR ALL INSTANCES.
292
© Copyright. All rights reserved.
Lesson: Defining and Implementing Global Interfaces
ENDMETHOD.
"constructor
METHOD on_partner_created.
APPEND sender TO mt_partners.
ENDMETHOD.
"on_partner_created
ENDCLASS.
"lcl_travel_agency IMPLEMENTATION
Include: BC401_GCL_S2_CARRIER
...
*---------------------------------------------------*
*
CLASS lcl_carrier DEFINITION
*---------------------------------------------------*
CLASS lcl_carrier DEFINITION.
PUBLIC SECTION.
INTERFACES if_partner.
METHODS:
constructor IMPORTING iv_name TYPE string,
on_airplane_created FOR EVENT airplane_created
OF lcl_airplane
IMPORTING sender,
display_attributes.
PRIVATE SECTION.
DATA:
mv_name
TYPE string,
mt_airplanes TYPE TABLE OF REF TO lcl_airplane.
METHODS:
display_airplanes.
ENDCLASS.
"lcl_carrier DEFINITION
*-------------------------------------------------*
*
CLASS lcl_carrier IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_airplane_created FOR ALL INSTANCES.
RAISE EVENT if_partner~partner_created.
ENDMETHOD.
"constructor
METHOD if_partner~display_partner.
display_attributes( ).
ENDMETHOD.
"if_partners~display_partner
METHOD on_airplane_created.
APPEND sender TO mt_airplanes.
ENDMETHOD.
"on_airplane_created
METHOD display_attributes.
SKIP 2.
WRITE: icon_flight AS ICON,
mv_name.
ULINE.
© Copyright. All rights reserved.
293
Unit 6: Object-Oriented Repository Objects
ULINE.
display_airplanes( ).
ENDMETHOD.
"display_attributes
METHOD display_airplanes.
DATA: lo_plane TYPE REF TO lcl_airplane.
LOOP AT mt_airplanes INTO lo_plane.
lo_plane->display_attributes( ).
ENDLOOP.
ENDMETHOD.
"display_airplanes
ENDCLASS.
"lcl_carrier IMPLEMENTATION
Include: BC401_GCL_S2_RENTAL
...
*---------------------------------------------------*
*
CLASS lcl_rental DEFINITION
*---------------------------------------------------*
CLASS lcl_rental DEFINITION.
PUBLIC SECTION.
INTERFACES:
if_partner.
METHODS:
constructor IMPORTING iv_name TYPE string,
on_vehicle_created FOR EVENT vehicle_created
OF lcl_vehicle
IMPORTING sender,
display_attributes.
PRIVATE SECTION.
DATA:
mv_name TYPE string,
mt_vehicles TYPE TABLE OF REF TO lcl_vehicle.
ENDCLASS.
"lcl_rental DEFINITION
*---------------------------------------------------*
*
CLASS lcl_rental IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_rental IMPLEMENTATION.
METHOD if_partner~display_partner.
display_attributes( ).
ENDMETHOD.
"if_partners~display_partner
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_vehicle_created FOR ALL INSTANCES.
RAISE EVENT if_partner~partner_created.
ENDMETHOD.
"constructor
METHOD on_vehicle_created.
APPEND sender TO mt_vehicles.
ENDMETHOD.
"on_vehicle_created
METHOD display_attributes.
DATA:
lo_vehicle TYPE REF TO lcl_vehicle.
WRITE: / icon_transport_proposal AS ICON,
294
© Copyright. All rights reserved.
Lesson: Defining and Implementing Global Interfaces
WRITE:
ULINE.
ULINE.
mv_name.
/ 'Here comes the vehicle list: '.
LOOP AT mt_vehicles INTO lo_vehicle.
lo_vehicle->display_attributes( ).
ENDLOOP.
ENDMETHOD.
"display_attributes
ENDCLASS.
"lcl_rental IMPLEMENTATION
Global Class Program: CL_HOTEL2
class CL_HOTEL2 definition
public
create public .
public section.
*"* public components of class CL_HOTEL2
*"* do not include other source files here!!!
interfaces IF_PARTNER .
methods CONSTRUCTOR
importing
!IV_NAME type STRING
!IV_BEDS type I .
methods DISPLAY_ATTRIBUTES .
class-methods DISPLAY_N_O_HOTELS .
protected section.
*"* protected components of class CL_HOTEL2
*"* do not include other source files here!!!
private section.
*"* private components of class CL_HOTEL2
*"* do not include other source files here!!!
data MV_NAME type STRING .
class-data GV_N_O_HOTELS type I .
data MV_BEDS type I .
constants C_POS_1 type I value 30. "#EC NOTEXT
ENDCLASS.
CLASS CL_HOTEL2 IMPLEMENTATION.
***** Instance Public Method CL_HOTEL2->CONSTRUCTOR
METHOD constructor .
mv_name = iv_name.
mv_beds = iv_beds.
ADD 1 TO gv_n_o_hotels.
RAISE EVENT if_partner~partner_created.
ENDMETHOD.
***** Instance Public Method CL_HOTEL2->DISPLAY_ATTRIBUTES
METHOD display_attribute .
ULINE.
WRITE:
/ 'Hotel'(001),
© Copyright. All rights reserved.
AT c_pos_1 mv_name,
295
Unit 6: Object-Oriented Repository Objects
/ 'Total number of beds:'(002), AT c_pos_1 mv_beds.
ULINE.
ULINE.
SKIP.
ENDMETHOD.
***** Static Public Method CL_HOTEL2=>DISPLAY_N_O_HOTELS
WRITE:
/ 'Total number of hotels:'(003), gv_n_o_hotels.
ENDMETHOD.
***** Instance Public Method CL_HOTEL2->IF_PARTNER~DISPLAY_PARTNER
METHOD if_partner~display_partner.
me->display_attributes( ).
ENDMETHOD.
ENDCLASS.
296
© Copyright. All rights reserved.
Lesson: Defining and Implementing Global Interfaces
LESSON SUMMARY
You should now be able to:
●
Define and implement global interfaces
●
Import local classes and interfaces
© Copyright. All rights reserved.
297
Unit 6
Lesson 3
Implementing Inheritance in Global Classes
LESSON OVERVIEW
This lesson explains how to generate UML diagrams using inheritance in global classes.
Business Example
As a developer, you need to generate UML diagrams, which help you to keep an overview over
your global classes and their relationships to each other. Additionally, you need to improve
the implementation of your hotel class by using inheritance. For this reason, you require the
following knowledge:
●
An understanding of how to generate UML diagrams
●
An understanding of how to handle global classes
●
An understanding of how to use refactoring assistant
LESSON OBJECTIVES
After completing this lesson, you will be able to:
298
●
Generate UML diagrams for global classes
●
Implement inheritance in global classes
●
Change the display of components in global classes
© Copyright. All rights reserved.
Lesson: Implementing Inheritance in Global Classes
Generation of UML Diagrams for Global Classes
Figure 118: Generate a UML Diagram for Package
In SAP NetWeaver 7.0 Enhancement Package 2 (EhP2), the Class Builder can generate UML
diagrams for existing coding. This function will display global classes if you select a package
to display. If however, you select a program, local classes and global interfaces will be
displayed, but not the global classes. However, the diagrams can include objects from ABAP
Dictionary.
The figure shows how to start the functionality for a complete package. In a dialog box, you
can add a selection of objects and specify which details you want to see on the diagram.
© Copyright. All rights reserved.
299
Unit 6: Object-Oriented Repository Objects
Inheritance in Global Classes
Figure 119: Defining an Inheritance Relationship
Set out the inheritance relationships between global classes on the Properties tab page.
Choose the Superclass button to specify a superclass. In the example shown in the figure,
Defining an Inheritance Relationship, the subclass ZCL_CARGO_PLANE_00 inherits from
superclass ZCL_AIRPLANE_00.
300
© Copyright. All rights reserved.
Lesson: Implementing Inheritance in Global Classes
Redefinition of a Method in Global Class
Figure 120: Redefining an Inherited Method
To redefine an inherited method, select the relevant method in the list and choose the
Redefine button. Alternatively, you can use the context menu in the navigation area.
Note:
The appearance of some of the buttons or menus depends on the release level.
The button for redefining methods is one example.
Hint:
To define the constructor in the subclass, choose the CONSTRUCTOR button in
the application toolbar. The system then proposes transferring the signature of
the superclass constructor. This is helpful when you want to create the subclass
constructor. You can add some parameters here. Similarly, you can find the call
for the superclass here.
© Copyright. All rights reserved.
301
Unit 6: Object-Oriented Repository Objects
Local Types in Global Classes
Figure 121: Defining a Local Type
You can define local types in global classes. Global classes include local classes.
Technically, you are not defining a class within a class, but a class that is local in the
repository object of the global class.
All components of the global class have access to these local types, but they are encapsulated
if you try to access them from outside.
The same applies for local interfaces in global classes.
There are two class includes for definition and implementation of local classes, as follows:
1. Local Definitions/Implementations
(formerly: Local Class Implementations):
This include contains local interfaces, local class definitions, local types, and local class
implementations that are not used in the private section of the global class (for example,
for typing a method parameter).
2. Class Relevant Local Definitions
(formerly: Local Types)
This include contains local interfaces, local class definitions, local types, and local class
implementations that are used in the private section of the global class (for example, for
typing a method parameter).
The includes can be entered by the menu Goto → Local Definitions/Implementations.
302
© Copyright. All rights reserved.
Lesson: Implementing Inheritance in Global Classes
Class Component Display
Figure 122: Structured Display of Inherited Components
To improve your understanding of inheritance and interface components, you can set the
Group by Classes and Interfacesflag in the User-Specific Settingsfor the Class Builder. The
system will then display the components of the global class in a group.
Sorting the Component Display of Global Classes
Figure 123: Sorting the Component Display of Global Classes
You can sort all components by five criteria in three levels. Choose the Sort pushbutton to
display the appropriate dialog box.
© Copyright. All rights reserved.
303
Unit 6: Object-Oriented Repository Objects
LESSON SUMMARY
You should now be able to:
304
●
Generate UML diagrams for global classes
●
Implement inheritance in global classes
●
Change the display of components in global classes
© Copyright. All rights reserved.
Unit 6
Learning Assessment
1. You can only use local classes or interfaces within the same program in which they are
defined and implemented.
Determine whether this statement is true or false.
X
True
X
False
2. The naming convention for SAP Standard Global Interfaces is ZIF_ or YIF_.
Determine whether this statement is true or false.
X
True
X
False
3. Which of the following buttons in Class Builder is used to override an inherited method?
Choose the correct answer.
X
A CONSTRUCTOR
X
B Redefine
X
C Implementation
4. Local types of the global class are encapsulated and cannot be accessed from outside.
Determine whether this statement is true or false.
X
True
X
False
© Copyright. All rights reserved.
305
Unit 6
Learning Assessment - Answers
1. You can only use local classes or interfaces within the same program in which they are
defined and implemented.
Determine whether this statement is true or false.
X
True
X
False
2. The naming convention for SAP Standard Global Interfaces is ZIF_ or YIF_.
Determine whether this statement is true or false.
X
True
X
False
3. Which of the following buttons in Class Builder is used to override an inherited method?
Choose the correct answer.
X
A CONSTRUCTOR
X
B Redefine
X
C Implementation
4. Local types of the global class are encapsulated and cannot be accessed from outside.
Determine whether this statement is true or false.
306
X
True
X
False
© Copyright. All rights reserved.
UNIT 7
ABAP Object-Oriented
Examples
Lesson 1
Using the ABAP List Viewer (ALV)
Exercise 18: Implement the ALV Grid Control
Exercise 19: Implement a Dialog Box with the ALV Grid Control
308
315
321
Lesson 2
Describing Business Add-Ins (BAdIs)
330
UNIT OBJECTIVES
●
Implement a simple ALV grid
●
Handle the double-click event of the ALV grid
●
Describe BAdls
© Copyright. All rights reserved.
307
Unit 7
Lesson 1
Using the ABAP List Viewer (ALV)
LESSON OVERVIEW
This lesson shows you how to implement ABAP List Viewer (ALV).
Business Example
You need to create a report using the ALV Grid Control. For this reason, you require the
following knowledge:
●
An understanding of the ALV Grid Control
●
An understanding of usage of an ALV in a screen area
●
An understanding of how to implement ALV
●
An understanding of implementation of a handler for the double-click event
●
An understanding of how to implement an event handler for the ALV Grid Control
●
An understanding of how to implement a popup with the ALV Grid Control
LESSON OBJECTIVES
After completing this lesson, you will be able to:
308
●
Implement a simple ALV grid
●
Handle the double-click event of the ALV grid
© Copyright. All rights reserved.
Lesson: Using the ABAP List Viewer (ALV)
The ALV Grid Control
Figure 124: The ALV Grid Control
The following topics illustrate the possible application areas of object-oriented ABAP
programming and the use of SAP standard classes. For example, ALV Grid Control in the
context of the Control Framework and the Business Add-Ins (BAdIs).
The SAP Control Framework is a collection of global classes and interfaces that you can use
to add SAP GUI controls in your ABAP Objects programs, regardless of the platform.
The ALV Grid Control is a tool that you can use to display non-hierarchical lists in a
standardized form. The list data displays in tables. It is easy to work with the tool, as there are
very few programming steps that must be carried out.
The ALV Grid Control contains a number of interactive standard functions that users of lists
often need, for example, print, export. As a developer, you have the option of hiding these
standard functions. When required, you can adapt the implementations to fit the needs of
your application. You can also add your own functions to the application toolbar.
© Copyright. All rights reserved.
309
Unit 7: ABAP Object-Oriented Examples
Including an ALV Grid Control Instance in a Dialog Program
Figure 125: Including an ALV Grid Control Instance in a Dialog Program
Container Controls provide the technical connection between the screen and application
controls. The application controls ALV Grid Control, Tree Control, and Picture Control are
always embedded in the Container Control, which is connected to the screen.
There are different types of container controls. However, all incorporate fundamental control
functions, such as scroll bars.
310
© Copyright. All rights reserved.
Lesson: Using the ABAP List Viewer (ALV)
Creation of an ALV
Figure 126: Displaying Application Data Using an ALV Grid Instance
You must place an ALV Grid Control in a screen area with a fixed size. To do this, you must
create an instance of each of the global classes CL_GUI_CUSTOM_CONTAINER and
CL_GUI_ALV_GRID.
For normal display, perform the following programming steps:
1. Use the full screen editor of the Screen Painter to define a custom control area on your
screen.
2. Create an instance of the class CL_GUI_CUSTOM_CONTAINER and transfer the name of
the custom control area to the constructor.
3. Create an instance of the class CL_GUI_GUI_ALV_GRID and transfer the reference to the
custom control instance to the constructor.
4. Call the method SET_TABLE_FOR_FIRST_DISPLAY of the grid control instance and
transfer the internal standard table to it, which contains the data to be displayed.
If the table has a global row type defined in ABAP Dictionary, you can transfer the name of this
global structure to the same method. The ALV Grid Control creates the field catalog
automatically
Caution:
The internal table transferred to the method SET_TABLE_FOR_FIRST_DISPLAY
must be globally defined. Therefore, the table must be either a global program
variable or a public attribute of a class.
When you change the contents of the internal tables while the program is running, you only
need to call the method REFRESH_TABLE_DISPLAY in the relevant dialog step to refresh the
display.
© Copyright. All rights reserved.
311
Unit 7: ABAP Object-Oriented Examples
Implementation of a Handler for the Double-Click Event
Figure 127: ALV Grid Control – Double-Click
An ALV Grid Control can react to the user’s double-click. As a possible reaction, you can
trigger a follow-on processing step in which additional information is displayed.
In the example shown in the figure ALV Grid Control – Double-Click, the booking data for the
individual flight customers or data on the aircraft, can also be displayed for the flight data.
This is executed by catching the event DOUBLE_CLICK with a handler method.
312
© Copyright. All rights reserved.
Lesson: Using the ABAP List Viewer (ALV)
ALV Grid Control – Reacting to a Double-Click
Figure 128: ALV Grid Control – Reacting to a Double-Click
A handler method is a class method (static method) or an instance method of an object. If a
class method is defined as a handler method, no object of the handled class needs to be
instantiated to use the method.
To create a handler object for an event, define a class. This class has a public method in the
public section that can react to an event. During the implementation of the handler method,
define the source text that must be run when the event is triggered. The method receives the
information that the event delivers from the mouse position when you double-click, and
creates an information message in the control example that displays the row and field of the
mouse click.
© Copyright. All rights reserved.
313
Unit 7: ABAP Object-Oriented Examples
Note:
Extensive documentation about the SAP Control Framework is available in the
standard SAP product documentation (delivered with the product or online
through the SAP Help portal). The SAP Library contains comprehensive
descriptions of all classes and a complete tutorial.
The ABAP Workbench also contains the Enjoy Demo Center
, which makes it easy
to use standard template programs. To find it use transaction DWDM (Development
Workbench Demos).
Individual elements of the SAP Control Framework are covered in other courses.
SAP also offers a separate comprehensive course about dialog programming with
the SAP controls. The course covers all aspects, including complex programming
techniques such as the drag and drop functions.
314
© Copyright. All rights reserved.
Unit 7
Exercise 18
Implement the ALV Grid Control
Business Example
You want to see a list of flight connections in an ALV Grid Control. When you double-click a
connection, the selected row number and column name must display.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_ALV_T1
Solution: SAPBC401_ALV_S1
Create an ALV Grid Control, and react to double-click the ALV Grid Control.
Program an ALV Grid Control
Program an ALV Grid Control and display the list of flight connections already stored in
internal table GT_SPFLI.
1. Copy the template program SAPBC401_ALV_T1 to ZBC401_##_ALV.
2. In the main program, define the reference variables GO_CONTAINER and GO_ALV_GRID
required for the ALV Grid Control.
3. Analyze the existing screen 100, paying particular attention to the name of the Custom
Container Control Area, which is used as the basis for the ALV Grid Control.
Implement the PBO module ALV_GRID. Use the reference variables to instantiate the two
classes in this PBO module. Pay attention to the fact that the CREATE OBJECT is not
called repeatedly when the PBO is executed repeatedly.
4. To display data in the ALV Grid Control, call the method
SET_TABLE_FOR_FIRST_DISPLAY and transfer the internal table with the flight
connection data and the name of the line type of that internal table.
5. Activate and test your program.
Caution:
You are working with a screen in this exercise, so always activate all parts of
the program as well as the screen.
Handle a Double-Click
Handle a double-click on the ALV Grid Control.
If the user double-clicks a row in the ALV Grid Control, the row number and column name
where the user double-clicked should be displayed in a message of type I.
1. Define a local class LCL_EVENT_HANDLER, and in this class, define an instance method to
handle the event DOUBLE_CLICK that the ALV Grid Control triggered.
© Copyright. All rights reserved.
315
Unit 7: ABAP Object-Oriented Examples
Note:
The class LCL_EVENT_HANDLER only acts as a handler and, otherwise, does
not have any other functions.
Import parameters ES_ROW_NO and E_COLUMN into the handler method.
2. Implement the handler method. Send a message of type I to output the row number and
column name that the user clicked.
3. Create the handler instance and register the handler method CREATE OBJECT
GO_HANDLER.
4. Activate and test your program.
316
© Copyright. All rights reserved.
Unit 7
Solution 18
Implement the ALV Grid Control
Business Example
You want to see a list of flight connections in an ALV Grid Control. When you double-click a
connection, the selected row number and column name must display.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_ALV_T1
Solution: SAPBC401_ALV_S1
Create an ALV Grid Control, and react to double-click the ALV Grid Control.
Program an ALV Grid Control
Program an ALV Grid Control and display the list of flight connections already stored in
internal table GT_SPFLI.
1. Copy the template program SAPBC401_ALV_T1 to ZBC401_##_ALV.
a) Carry out this step as usual.
2. In the main program, define the reference variables GO_CONTAINER and GO_ALV_GRID
required for the ALV Grid Control.
a) Review the source code extract from the model solution or refer to the corresponding
slides about the ALV Grid Control.
3. Analyze the existing screen 100, paying particular attention to the name of the Custom
Container Control Area, which is used as the basis for the ALV Grid Control.
Implement the PBO module ALV_GRID. Use the reference variables to instantiate the two
classes in this PBO module. Pay attention to the fact that the CREATE OBJECT is not
called repeatedly when the PBO is executed repeatedly.
a) Review the source code extract from the model solution, or refer to the corresponding
slides about the ALV Grid Control. Speak to your instructor if you have any questions.
4. To display data in the ALV Grid Control, call the method
SET_TABLE_FOR_FIRST_DISPLAY and transfer the internal table with the flight
connection data and the name of the line type of that internal table.
a) Review the source code extract from the model solution, or refer to the corresponding
slides about the ALV Grid Control. Speak to your instructor if you have any questions.
5. Activate and test your program.
Caution:
You are working with a screen in this exercise, so always activate all parts of
the program as well as the screen.
© Copyright. All rights reserved.
317
Unit 7: ABAP Object-Oriented Examples
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
d) To run your program, on the application toolbar, choose the Direct Processingbutton.
Handle a Double-Click
Handle a double-click on the ALV Grid Control.
If the user double-clicks a row in the ALV Grid Control, the row number and column name
where the user double-clicked should be displayed in a message of type I.
1. Define a local class LCL_EVENT_HANDLER, and in this class, define an instance method to
handle the event DOUBLE_CLICK that the ALV Grid Control triggered.
Note:
The class LCL_EVENT_HANDLER only acts as a handler and, otherwise, does
not have any other functions.
Import parameters ES_ROW_NO and E_COLUMN into the handler method.
a) See the source code extract from the model solution.
2. Implement the handler method. Send a message of type I to output the row number and
column name that the user clicked.
a) In the ON_DOUBLE_CLICK method of class LCL_EVENT_HANDLER enter the following
code:
MESSAGE i010(bc401) WITH es_row_no-row_id e_column-fieldname
3. Create the handler instance and register the handler method CREATE OBJECT
GO_HANDLER.
a) Between instantiating the class CL_GUI_ALV_GRID and calling the method
SET_TABLE_FOR_FIRST_DISPLAY enter the following code:
SET HANDLER go_handler->on_double_click FOR go_alv_grid.
4. Activate and test your program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
d) To run your program, on the application toolbar, choose the Direct Processingbutton.
e) Carry out this step in the usual manner. Make sure that the program displays as
follows:
SAPBC401_ALV_S1
REPORT
sapbc401_alv_s1.
*-------------------------------------------------*
*
CLASS lcl_event_handler DEFINITION
*-------------------------------------------------*
318
© Copyright. All rights reserved.
Lesson: Using the ABAP List Viewer (ALV)
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
METHODS on_double_click FOR EVENT double_click
OF cl_gui_alv_grid
IMPORTING es_row_no e_column.
ENDCLASS.
"lcl_event_handler DEFINITION
*-------------------------------------------------*
*
CLASS lcl_event_handler IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_event_handler IMPLEMENTATION.
METHOD on_double_click.
MESSAGE i010(bc401) WITH
es_row_no-row_id e_column-fieldname.
ENDMETHOD.
ENDCLASS.
"handler_method
"lcl_event_handler IMPLEMENTATION
*** Types and Data Definitions
TYPES:
ty_spfli TYPE STANDARD TABLE OF spfli
WITH NON-UNIQUE KEY carrid connid.
DATA: ok_code TYPE sy-ucomm.
DATA: go_handler TYPE REF TO lcl_event_handler,
go_container TYPE REF TO cl_gui_custom_container,
go_alv_grid TYPE REF TO cl_gui_alv_grid.
DATA: gt_spfli TYPE ty_spfli.
START-OF-SELECTION.
********************
SELECT * FROM spfli INTO TABLE gt_spfli.
CALL SCREEN '0100'.
*&----------------------------------------------*
*&
Module STATUS_0100 OUTPUT
*&----------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'DYNPROSTATUS'.
SET TITLEBAR 'TITLE1'.
ENDMODULE.
" STATUS_0100 OUTPUT
*&----------------------------------------------*
*&
Module ALV_GRID OUTPUT
*&----------------------------------------------*
MODULE alv_grid OUTPUT.
** Create object of class CL_GUI_CUSTOM_CONTAINER
** to manage data
IF go_container IS NOT BOUND.
CREATE OBJECT go_container
EXPORTING
© Copyright. All rights reserved.
319
Unit 7: ABAP Object-Oriented Examples
container_name = 'CONTAINER_1'
EXCEPTIONS
others
= 6.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
** create object of class cl_gui_alv_grid to visualize data
CREATE OBJECT go_alv_grid
EXPORTING
i_parent = go_container
EXCEPTIONS
others
= 5.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
** create handler instance and register handler method
CREATE OBJECT go_handler.
SET HANDLER go_handler->on_double_click FOR go_alv_grid.
** Call method to visualize data of internal table
CALL METHOD go_alv_grid->set_table_for_first_display
EXPORTING
i_structure_name = 'SPFLI'
CHANGING
it_outtab
= gt_spfli
EXCEPTIONS
OTHERS
= 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.
ENDMODULE.
" ALV_GRID
OUTPUT
*&-----------------------------------------------*
*&
Module USER_COMMAND_0100 INPUT
*&-----------------------------------------------*
MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'BACK'.
SET SCREEN 0.
WHEN 'EXIT'.
LEAVE PROGRAM.
ENDCASE.
ENDMODULE.
320
" USER_COMMAND_0100
INPUT
© Copyright. All rights reserved.
Unit 7
Exercise 19
Implement a Dialog Box with the ALV Grid
Control
Business Example
You need to see a list of flight connections in an ALV Grid Control. When you double-click one
connection, the list of flights for this connection must be displayed in a second ALV Grid
Control.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template:SAPBC401_ALV_S1
Solution: SAPBC401_ALV_S2
Read from a Database Table
Read from the database table SFLIGHT about the flights that belong to the flight connection
that you double-clicked.
1. Complete your program ZBC401_##_ALV or copy the model solution from the previous
exercise.
2. In the event handler method, remove the MESSAGE statement. Define a local structure
(suggested name - LS_SPFLI), to serve as a work area for internal table GT_SPFLI. From
GT_SPFLI, read the entry that corresponds to the grid row that you double-clicked.
Hint:
Use READ TABLE with an index access.
3. Is defining GT_SPFLI after the definition of the event handler class acceptable?
4. In the definition of the event handler class, define a private instance attribute
MT_SFLIGHT, which is an internal (standard) table with line type SFLIGHT.
Hint:
Define a private table type TY_SFLIGHT in the same class.
© Copyright. All rights reserved.
321
Unit 7: ABAP Object-Oriented Examples
5. In the event handler method, implement an array fetch for database table SFLIGHT to fill
MT_SFLIGHT with those flights that have the same key fields as the flight connection that
you have clicked.
6. Activate your program and analyze it in the ABAP Debugger. Make sure that MT_SFLIGHT
is filled correctly.
Extend the Event Handler Method
Extend your event handler method so that the selected flights are presented in a second ALV
Grid Control, which is displayed in a dialog box.
1. In your event handler class, define two reference variables as private instance attributes
(suggested names – MO_CONT_POPUP and MO_ALV_POPUP). Type them with the global
classes CL_GUI_DIALOGBOX_CONTAINER and CL_GUI_ALV_GRID.
2. In your event handler method, use these reference variables to create instances of the two
classes.
Make sure that the CREATE OBJECT statement is not called repeatedly when the event
handler method is executed repeatedly.
3. To display data in the ALV Grid Control, call the method
SET_TABLE_FOR_FIRST_DISPLAY and transfer the internal table MT_SFLIGHT with the
flight data and the name of the line type of that internal table.
Make sure that this method is only called if the dialog box container and the second ALV
Grid Control have just been created.
4. If the dialog box container and the second ALV Grid Control already exist, do not call
method SET_TABLE_FOR_FIRST_DISPLAY to refresh the data displayed. Call the method
REFRESH_TABLE_DISPLAY instead.
Hint:
You do not have to provide values for the optional parameters of this method.
5. Activate and test your program.
Note:
At this point, clicking the button in the top-right corner of the window does not
close the dialog box container. To implement this function, you must handle
event CLOSE of class CL_GUI_DIALOGBOX_CONTAINER and call method
FREE of the dialog box container. Other training courses and the Control
Framework documentation explain this procedure in detail.
322
© Copyright. All rights reserved.
Unit 7
Solution 19
Implement a Dialog Box with the ALV Grid
Control
Business Example
You need to see a list of flight connections in an ALV Grid Control. When you double-click one
connection, the list of flights for this connection must be displayed in a second ALV Grid
Control.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template:SAPBC401_ALV_S1
Solution: SAPBC401_ALV_S2
Read from a Database Table
Read from the database table SFLIGHT about the flights that belong to the flight connection
that you double-clicked.
1. Complete your program ZBC401_##_ALV or copy the model solution from the previous
exercise.
a) Carry out this step as usual.
2. In the event handler method, remove the MESSAGE statement. Define a local structure
(suggested name - LS_SPFLI), to serve as a work area for internal table GT_SPFLI. From
GT_SPFLI, read the entry that corresponds to the grid row that you double-clicked.
Hint:
Use READ TABLE with an index access.
a) See the source code extract from the model solution.
3. Is defining GT_SPFLI after the definition of the event handler class acceptable?
No. To be able to access the global data object GT_SPFLI from within the local class
implementation, the data object must be defined as global program variable before the
local class definition.
4. In the definition of the event handler class, define a private instance attribute
MT_SFLIGHT, which is an internal (standard) table with line type SFLIGHT.
© Copyright. All rights reserved.
323
Unit 7: ABAP Object-Oriented Examples
Hint:
Define a private table type TY_SFLIGHT in the same class.
a) See the source code extract from the model solution.
5. In the event handler method, implement an array fetch for database table SFLIGHT to fill
MT_SFLIGHT with those flights that have the same key fields as the flight connection that
you have clicked.
a) See the source code extract from the model solution.
6. Activate your program and analyze it in the ABAP Debugger. Make sure that MT_SFLIGHT
is filled correctly.
a) Carry out this step in the usual manner.
Extend the Event Handler Method
Extend your event handler method so that the selected flights are presented in a second ALV
Grid Control, which is displayed in a dialog box.
1. In your event handler class, define two reference variables as private instance attributes
(suggested names – MO_CONT_POPUP and MO_ALV_POPUP). Type them with the global
classes CL_GUI_DIALOGBOX_CONTAINER and CL_GUI_ALV_GRID.
a) See the source code extract from the model solution.
2. In your event handler method, use these reference variables to create instances of the two
classes.
Make sure that the CREATE OBJECT statement is not called repeatedly when the event
handler method is executed repeatedly.
a) See the source code extract from the model solution.
3. To display data in the ALV Grid Control, call the method
SET_TABLE_FOR_FIRST_DISPLAY and transfer the internal table MT_SFLIGHT with the
flight data and the name of the line type of that internal table.
Make sure that this method is only called if the dialog box container and the second ALV
Grid Control have just been created.
a) See the source code extract from the model solution.
4. If the dialog box container and the second ALV Grid Control already exist, do not call
method SET_TABLE_FOR_FIRST_DISPLAY to refresh the data displayed. Call the method
REFRESH_TABLE_DISPLAY instead.
Hint:
You do not have to provide values for the optional parameters of this method.
a) See the source code extract from the model solution.
5. Activate and test your program.
324
© Copyright. All rights reserved.
Lesson: Using the ABAP List Viewer (ALV)
Note:
At this point, clicking the button in the top-right corner of the window does not
close the dialog box container. To implement this function, you must handle
event CLOSE of class CL_GUI_DIALOGBOX_CONTAINER and call method
FREE of the dialog box container. Other training courses and the Control
Framework documentation explain this procedure in detail.
a) Carry out this step in the usual manner.
SAPBC401_ALV_S2
REPORT
sapbc401_alv_s2.
TYPES:
ty_spfli TYPE STANDARD TABLE OF spfli
WITH NON-UNIQUE KEY carrid connid.
DATA: gt_spfli TYPE ty_spfli.
*--------------------------------------------------*
*
CLASS lcl_event_handler DEFINITION
*--------------------------------------------------*
*
*--------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
METHODS on_double_click FOR EVENT double_click
OF cl_gui_alv_grid
IMPORTING es_row_no e_column.
PRIVATE SECTION.
TYPES: ty_sflight TYPE STANDARD TABLE OF sflight
WITH NON-UNIQUE KEY carrid connid fldate.
DATA: mo_cont_popup TYPE REF TO cl_gui_dialogbox_container,
mo_alv_popup TYPE REF TO cl_gui_alv_grid.
DATA: mt_sflight TYPE ty_sflight.
ENDCLASS.
"lcl_event_handler DEFINITION
*--------------------------------------------------*
*
CLASS lcl_event_handler IMPLEMENTATION
*--------------------------------------------------*
*
*--------------------------------------------------*
CLASS lcl_event_handler IMPLEMENTATION.
METHOD on_double_click.
DATA ls_spfli TYPE spfli.
READ TABLE gt_spfli INTO ls_spfli
INDEX es_row_no-row_id.
SELECT * FROM sflight INTO TABLE mt_sflight
© Copyright. All rights reserved.
325
Unit 7: ABAP Object-Oriented Examples
WHERE carrid = ls_spfli-carrid
AND connid = ls_spfli-connid.
IF mo_cont_popup IS NOT BOUND.
CREATE OBJECT mo_cont_popup
EXPORTING
width = 600
height = 300
EXCEPTIONS
others = 8.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CREATE OBJECT mo_alv_popup
EXPORTING
i_parent = mo_cont_popup
EXCEPTIONS
others
= 5.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
mo_alv_popup->set_table_for_first_display(
EXPORTING
i_structure_name
= 'SFLIGHT'
CHANGING
it_outtab
= mt_sflight
EXCEPTIONS
OTHERS
= 4
).
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ELSE.
mo_alv_popup->refresh_table_display(
EXCEPTIONS
OTHERS
= 2
).
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.
* MESSAGE i010(bc401) WITH
*
es_row_no-row_id e_column-fieldname.
ENDMETHOD.
ENDCLASS.
"handler_method
"lcl_event_handler IMPLEMENTATION
DATA: ok_code TYPE sy-ucomm.
DATA: go_handler TYPE REF TO lcl_event_handler,
326
© Copyright. All rights reserved.
Lesson: Using the ABAP List Viewer (ALV)
go_container TYPE REF TO cl_gui_custom_container,
go_alv_grid TYPE REF TO cl_gui_alv_grid.
START-OF-SELECTION.
********************
SELECT * FROM spfli INTO TABLE gt_spfli.
CALL SCREEN '0100'.
*&------------------------------------------------*
*&
Module STATUS_0100 OUTPUT
*&------------------------------------------------*
*
text
*-------------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'DYNPROSTATUS'.
SET TITLEBAR 'TITLE1'.
ENDMODULE.
" STATUS_0100 OUTPUT
*&------------------------------------------------*
*&
Module ALV_GRID OUTPUT
*&------------------------------------------------*
*
text
*-------------------------------------------------*
MODULE alv_grid OUTPUT.
* Create object of class CL_GUI_CUSTOM_CONTAINER to
* manage data
IF go_container IS NOT BOUND.
CREATE OBJECT go_container
EXPORTING
container_name = 'CONTAINER_1'
EXCEPTIONS
others
= 6.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* create object of class cl_gui_alv_grid to visualize data
CREATE OBJECT go_alv_grid
EXPORTING
i_parent = go_container
EXCEPTIONS
others
= 5.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
** create handler Instance
CREATE OBJECT go_handler.
** set handler to react on double-click
SET HANDLER go_handler->on_double_click FOR go_alv_grid.
** Call method to visualize data of internal table
CALL METHOD go_alv_grid->set_table_for_first_display
EXPORTING
© Copyright. All rights reserved.
327
Unit 7: ABAP Object-Oriented Examples
i_structure_name = 'SPFLI'
CHANGING
it_outtab
= gt_spfli
EXCEPTIONS
OTHERS
= 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.
ENDMODULE.
" ALV_GRID
OUTPUT
*&-------------------------------------------------*
*&
Module USER_COMMAND_0100 INPUT
*&-------------------------------------------------*
MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'BACK'.
SET SCREEN 0.
WHEN 'EXIT'.
LEAVE PROGRAM.
ENDCASE.
ENDMODULE.
328
" USER_COMMAND_0100
INPUT
© Copyright. All rights reserved.
Lesson: Using the ABAP List Viewer (ALV)
LESSON SUMMARY
You should now be able to:
●
Implement a simple ALV grid
●
Handle the double-click event of the ALV grid
© Copyright. All rights reserved.
329
Unit 7
Lesson 2
Describing Business Add-Ins (BAdIs)
LESSON OVERVIEW
This lesson shows you how to implement Business Add-Ins (BAdIs).
Business Example
You need to enhance functionality in an SAP standard program, without altering the original
program. This can be done by using BAdIs. For this reason, you require the following
knowledge:
●
An understanding of BAdIs
●
An understanding of how to define a BAdI
●
An understanding of how to implement a BAdI
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Describe BAdls
BAdIs
Unlike Customer Exits, BAdIs are optimized for the changed software delivery process.
The typical software delivery process does not only consist of providers and customers,
rather several intermediate providers may be involved in the delivery chain for software. For
example, an SAP partner can extend an SAP application program with an industry solution
like Industrial Business Unit (IBU). The customer can then again extend the same program.
330
© Copyright. All rights reserved.
Lesson: Describing Business Add-Ins (BAdIs)
BAdI – Basics
Figure 129: BAdI – Basics
With a BAdI, an SAP application provides the enhancement option through an interface and
an adapter class implementing that interface.
The interface can be implemented by several users in the delivery chain, thus, multiple BAdI
implementations are possible. Additionally, a BAdI implementation itself can provide another
BAdI, which can be implemented by users who appear further out in the delivery chain.
© Copyright. All rights reserved.
331
Unit 7: ABAP Object-Oriented Examples
Definition of a BAdI – Basics
Figure 130: Definition of a BAdI – Basics
When you define a BAdI, you must specify an interface (IF_EX_<badi>) with corresponding
formally defined methods. The adapter class that is automatically generated during the
interface definition (CL_EX_<badi>) has, among other capabilities, the function of calling all
active implementations of the BAdI. When you have several active implementations, there is
no predefined processing sequence.
To Define a BAdI
1. Run the transaction SE18 or, on the SAP Easy Access screen, choose Tools → ABAP
Workbench → Utilities → Business Add-Ins → Definition.
As of SAP Netweaver 7.0, you cannot directly create a BAdI. First, you must create an
Enhancement Spot.
2. Enter the Enhancement Spotname and choose the Create button.
A Create Enhancement Spotdialog displays.
3. In the Create Enhancement Spotdialog, enter a short description, and choose the Creation
of an Enhancementbutton. Save the enhancement to your package.
4. Choose the Create BadI button.
A Create BAdI Definitiondialog displays.
5. Enter a short description and choose the Continue button.
6. In the BAdI Definition screen area, expand the node, and double-click Interface.
332
© Copyright. All rights reserved.
Lesson: Describing Business Add-Ins (BAdIs)
7. Enter your interface name ZIF_BC401_00_BADI_DEMO and press Enter.
A Class/Interface dialog box displays.
8. On the Class/Interface dialog, choose Yes to create the interface. Save it to your package,
then save the enhancement spot.
The class builder will display on the Method tab page.
9. Enter an instance method and a description, and activate the interface.
The BAdI Calling Program
Figure 131: BAdI – The Calling Program
The figure, BAdI – The Calling Program, shows an example of a BAdI call.
A reference variable for the type of BAdI must be defined.
An object of the adapter class is instantiated by the call of the GET_INSTANCE static method
of the CL_EXITHANDLER class. The variable gb_adapter points to this instance.
The interface methods of the BAdI can be called by gb_adapter object reference.
The Search for BAdIs
You can search the BAdI using the following strategies:
●
You can use the Repository Information System (transaction SE84).
●
You can use the Application Hierarchy (transaction SE81).
●
You can use the Customizing Guide (Implementation guide for transaction SPRO).
© Copyright. All rights reserved.
333
Unit 7: ABAP Object-Oriented Examples
●
You can search in the application source code for the
CL_EXITHANDLER=>GET_INSTANCE statement.
●
You can search in the application source code for the occurrence of the BAdI interfaces
with the naming convention IF_EX_.
●
As of SAP Netweaver AS 7.0, you can search in the application source code for
occurrences of the GET BADI statement.
The name of the BAdl must be investigated before you can implement the BAdI. When
searching for BAdI names, you can use the search mechanisms. Double-click the reference
variable (gb_adapter) in the example to get the interface definition. You can derive the BAdI
name from the name of the interface.
Note:
How to search in ABAP source code:
When running an arbitrary transaction press F1 key. On the displayed dialog box,
choose the Technical Informationbutton. Navigate to the source code of the
program by double-clicking the program name. Then call the global search
function in menu Edit → Find Next and search for the desired string.
Do not use the editor's search function Edit → Find/Replace (Ctrl + F), because
this function will consider a single source code include only.
BAdI Implementation
Figure 132: Implementation of a BAdI – SE19
334
© Copyright. All rights reserved.
Lesson: Describing Business Add-Ins (BAdIs)
When the name of the BAdI is determined, the BAdI can be implemented. The implementation
of the BAdI is performed through the implementation maintenance under Tools →ABAP
Workbench →Utilities →Business Add-Ins →Implementation (transaction code SE19).
Alternatively, you can go to the implementations by navigating the menu from the BAdI
definition.
To implement a BAdI, a BAdI implementation name must be issued. The naming convention is
Z<impl>. A dialog box then appears for selecting the corresponding BAdI.
The code to be implemented is stored in a method of an automatically generated customer
class. For this reason, the name of the implementing class must be given in a final dialog box.
The default name from SAP is comprised of Y or Z (the namespace prefix), CL_ (for class),
IM_ (for implementation), and <impl> (the actual name of the implementation).
When you double-click one of the BAdI methods, you can enter the code of the method. You
can also create auxiliary methods in the implementing class to better structure the required
code of the BAdI method.
Note:
Activate the methods of the implementations at the end of the task.
To Implement a BAdI
1. Run the transaction code SE19.
2. Enter the BAdI definition name (or Enhancement Spotname) and choose the Create
button.
3. Enter an implementation name and choose the OK button.
4. Enter a description text and choose the Save button.
5. Double-click the name of the implementing class to navigate to the class and implement
your source code there.
LESSON SUMMARY
You should now be able to:
●
Describe BAdls
© Copyright. All rights reserved.
335
Unit 7: ABAP Object-Oriented Examples
336
© Copyright. All rights reserved.
Unit 7
Learning Assessment
1. The ABAP List Viewer (ALV) Grid Control is a tool that you can use to display
nonhierarchical lists in a standardized form.
Determine whether this statement is true or false.
X
True
X
False
2. Container controls provide the technical connection between the screen and the
application control.
Determine whether this statement is true or false.
X
True
X
False
3. To create a handler object for an event, we must first define a ____________.
Choose the correct answer.
X
A class
X
B structure
X
C screen
X
D attribute
4. A handler method can be either a class method (static method) or an instance method of
an object.
Determine whether this statement is true or false.
X
True
X
False
© Copyright. All rights reserved.
337
Unit 7: Learning Assessment
5. With a Business Add-In (BAdI), an SAP application program provides the enhancement
option through an interface method.
Determine whether this statement is true or false.
X
True
X
False
6. An object of the BAdI adapter class is instantiated by the call of the static method
GET_INSTANCE of the class CL_EXITHANDLER.
Determine whether this statement is true or false.
X
True
X
False
7. To implement a Business Add-In (BAdI), the BADI definition name must be determined.
Determine whether this statement is true or false.
X
True
X
False
8. The code of a BAdI implementation is stored in a __________ of an automatically generated
customer class.
Choose the correct answer.
338
X
A method
X
B structure
X
C object
© Copyright. All rights reserved.
Unit 7
Learning Assessment - Answers
1. The ABAP List Viewer (ALV) Grid Control is a tool that you can use to display
nonhierarchical lists in a standardized form.
Determine whether this statement is true or false.
X
True
X
False
2. Container controls provide the technical connection between the screen and the
application control.
Determine whether this statement is true or false.
X
True
X
False
3. To create a handler object for an event, we must first define a ____________.
Choose the correct answer.
X
A class
X
B structure
X
C screen
X
D attribute
4. A handler method can be either a class method (static method) or an instance method of
an object.
Determine whether this statement is true or false.
X
True
X
False
© Copyright. All rights reserved.
339
Unit 7: Learning Assessment - Answers
5. With a Business Add-In (BAdI), an SAP application program provides the enhancement
option through an interface method.
Determine whether this statement is true or false.
X
True
X
False
6. An object of the BAdI adapter class is instantiated by the call of the static method
GET_INSTANCE of the class CL_EXITHANDLER.
Determine whether this statement is true or false.
X
True
X
False
7. To implement a Business Add-In (BAdI), the BADI definition name must be determined.
Determine whether this statement is true or false.
X
True
X
False
8. The code of a BAdI implementation is stored in a __________ of an automatically generated
customer class.
Choose the correct answer.
340
X
A method
X
B structure
X
C object
© Copyright. All rights reserved.
UNIT 8
Global Classes in ABAP
Development Tools
Lesson 1
Developing Eclipse-Based ABAP Programs
Exercise 20: Edit a Global Class and an Executable Program in ABAP Development
Tools (ADT)
Exercise 21: Use Refactoring Functions in ADT
UNIT OBJECTIVES
●
Implement Eclipse-based ABAP development
●
Use quick fixes and refactoring
© Copyright. All rights reserved.
341
342
349
363
Unit 8
Lesson 1
Developing Eclipse-Based ABAP Programs
LESSON OVERVIEW
This lesson explains how to use ABAP Development Tools (ADT). ADT is based on the Eclipse
framework.
ADT offers functions which are not available in the ABAP Workbench. These functions are
especially useful when writing object oriented code.
Business Example
You have heard that SAP offers the possibility of ABAP development in Eclipse, and that
developing ABAP in Eclipse is particularly useful for writing object oriented code. Therefore,
you want to learn more about this possibility.
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement Eclipse-based ABAP development
●
Use quick fixes and refactoring
ABAP Development Tools
ABAP Development Tools (ADT) is an alternative to the ABAP Workbench. ADT provides the
following features:
342
●
An ABAP development experience on top of the Eclipse platform.
●
An open platform for developing new ABAP-related tools.
●
A set of open, language-independent, and platform-independent APIs that developers can
use to build new custom tools for the ABAP environment.
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
Figure 133: ABAP Development Tools Eclipse Based ABAP Development
The ABAP Perspective
Eclipse allows development in many different programming languages. To support different
types of development, Eclipse contains different combinations of tools, called Perspectives. If
you have ADT installed, you can switch to the ABAP perspective. Choose Window → Open
Perspective → Other... → ABAP in the menu bar or choose the Open Perspectivebutton.
Figure 134: Switching to the ABAP Perspective
© Copyright. All rights reserved.
343
Unit 8: Global Classes in ABAP Development Tools
Creation of an ABAP Project
Figure 135: ADT Getting Started Creating a Project
When you use ADT, you log on to an SAP back-end system and work directly with its
repository objects. Therefore, the development process is exactly the same as when you use
the ABAP Workbench, there is no check-out and check-in of the objects.
An ABAP project serves as a container for the development objects that are stored in a
particular ABAP back-end system, and contains the logon parameters for the system logon —
System, Client, User, and language. You must be logged on to the system to edit an object.
Within the ABAP project, you can access any development object in the repository. In
addition, to make it easier to manage objects you can set up favorite packages for each
project.
344
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
Object Editing
Figure 136: ADT Editing Repository Objects
The Project Explorer provides a hierarchical view of the repository, similar to the navigation
area of the ABAP workbench. Under each project, you can maintain a list of favorite packages.
By expanding the node System Library, you see a list of all packages.
To open a specific repository object in its respective editor, double-click it. The editor is
shown on the right side of the ABAP perspective. For each new object, a new tab is added.
This simplifies the navigation between editors and objects.
© Copyright. All rights reserved.
345
Unit 8: Global Classes in ABAP Development Tools
Types of Editors
Figure 137: Native Editors or Integrated SAP GUI Editors
There are two kinds of editors in ADT – there is a native Eclipse implementation and an SAP
GUI based implementation. In the figure, Native Editors and Integrated SAP GUI Editors, you
can see an example of each of the following types:
There are two types of editors in the ABAP development tools:
●
Editors for which there is a native Eclipse implementation
For example, ABAP Editor, an Eclipse editor
●
Editors that are displayed in an in-place SAP graphical user interface (GUI)
For example, ABAP transaction editor with the classic SAP GUI visualization appearing
within the Eclipse environment
There is no requirement to use ADT for ABAP Development, and each developer is free to
choose whether to use ADT or the classic ABAP Workbench. The functions and features of
Eclipse and ADT lend themselves particularly well to object-oriented programming, among
these features are various built-in refactoring functions and support for unit testing. There are
other tasks to which the ABAP Workbench is better suited — in particular working with
module pools and screens.
Documentation, Installation, and Support for ABAP Development Tools
If you are looking for a local installation of ADT, you can choose from the following sources:
●
346
SAP Software Download Center (http://service.sap.com/swdc), a part of the SAP Service
Marketplace.
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
●
SAP Development Tools for Eclipse Web site (http://tools.hana.ondemand.com). You can
also find other products, such as the SAP HANA studio or the tools for SAP UI5
development on this site.
●
SAP Community Network pages (http://scn.sap.com/community/abap/eclipse and
http://scn.sap.com/community/abap/hana). They provide documentation and support
on how to install the SAP Development Tools for Eclipse.
© Copyright. All rights reserved.
347
Unit 8: Global Classes in ABAP Development Tools
348
© Copyright. All rights reserved.
Unit 8
Exercise 20
Edit a Global Class and an Executable Program
in ABAP Development Tools (ADT)
Business Example
You have to create another global class, and would like to take advantage of the Quick Fix
functionality available for Classes in ABAP Development Tools to complete this task in an
efficient way.
Note:
This exercise uses the main program ZBC401_##_MAIN and the global class
ZCL_##_HOTEL completed in the previous exercises. If not complete, copy the
model solution from the previous exercise and the global class. In the exercises for
this course, when the input values include ##, replace ## with your group
number.
Templates:
●
SAPBC401_GCL_S1 (program)
●
CL_HOTEL2 (global class)
Solutions:
●
SAPBC401_ADT_S1 (program)
●
CL_HOTEL3 (global class)
●
CL_ROOM (global class)
Create an ABAP Project
Create an ABAP project and add your package to the new project.
1. Launch ABAP Development Toolsand create an ABAP project.
Define and Implement a Global Class
Create, define, and implement a global class for rooms. Use the quick fix functionality to add
the method implementations after you have defined the methods.
1. Create the global class ZCL_##_ROOM.
2. Define the following private instance attributes in the class ZCL_ROOM:
Table 5: Public Instance Attributes
Attribute Name
Type
MV_NUMBER
S_ROOM_NUMBER
© Copyright. All rights reserved.
349
Unit 8: Global Classes in ABAP Development Tools
Attribute Name
Type
MV_BEDS
I
3. Define the public instance constructor with the two import parameters IV_NUMBER and
IV_BEDS.
4. Define the public instance method GET_BEDS with returning parameter RV_BEDS.
5. Define a public instance event ROOM_CREATED with no parameters.
6. Use the Quick Fix functionality to add the method implementations. Then implement the
methods.
7. Save and activate the global class.
Add Instances Rooms to the Hotel
Aggregate instances of ZCL_##_ROOM in your class ZCL_##_HOTEL.
Note:
Edit the class ZCL_##_HOTEL for all steps of this task.
1. Define the private instance attribute MT_ROOMS with type TABLE OF REF TO
ZCL_##_ROOM.
2. Define an event handler method for event ROOM_CREATED of class ZCL_##_ROOM.
3. Implement the event handler method for event ROOM_CREATED of class ZCL_##_ROOM
and append the sender to the list of rooms.
4. In the constructor of ZCL_##_HOTEL, register the handler FOR ALL INSTANCES of
ZCL_##_ROOM.
5. In the implementation of the DISPLAY_ATTRIBUTES method, define a local variable
LV_SUM_OF_BEDS of type i and a local reference variable LO_ROOM of type REF TO
ZCL_##_ROOM.
6. In the implementation of the DISPLAY_ATTRIBUTES method, edit the WRITE statement,
replace the MV_BEDS attribute with the local variable.
7. Before the WRITE statement, add a loop over the aggregated rooms. Call method
GET_BEDS for each room and add the result to LV_SUM_OF_BEDS.
8. Remove parameter IV_BEDS from the definition and implementation of the constructor of
ZCL_##_HOTEL. Delete unused attribute MV_BEDS.
9. Save and activate the global class.
Create Instances of the Room Class
In your main program, create several instances of ZCL_##_ROOM to be aggregated in the
instance of your hotel class.
Note:
Edit your main program for all steps of this task.
350
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
1. Define a reference variable for instances of ZCL_##_ROOM called GO_ROOM with TYPE
REF TO ZCL_##_ROOM.
2. Create several instances of the class, using the reference variable GO_ROOM.
3. The rooms are to be aggregated into the hotel through the ROOM_CREATED event. Where
is the earliest point in your program where you can create the room instances?
4. Save, activate, and run your program.
© Copyright. All rights reserved.
351
Unit 8
Solution 20
Edit a Global Class and an Executable Program
in ABAP Development Tools (ADT)
Business Example
You have to create another global class, and would like to take advantage of the Quick Fix
functionality available for Classes in ABAP Development Tools to complete this task in an
efficient way.
Note:
This exercise uses the main program ZBC401_##_MAIN and the global class
ZCL_##_HOTEL completed in the previous exercises. If not complete, copy the
model solution from the previous exercise and the global class. In the exercises for
this course, when the input values include ##, replace ## with your group
number.
Templates:
●
SAPBC401_GCL_S1 (program)
●
CL_HOTEL2 (global class)
Solutions:
●
SAPBC401_ADT_S1 (program)
●
CL_HOTEL3 (global class)
●
CL_ROOM (global class)
Create an ABAP Project
Create an ABAP project and add your package to the new project.
1. Launch ABAP Development Toolsand create an ABAP project.
a) Choose Start → All Programs → ABAP Development Tools → ABAP Development
Tools.
The Workspace Launcherdialog box displays.
b) In the Workspace Launcherdialog box, accept the default workspace and choose OK.
c) Choose Workbench on the top right side of the editor (this is only for the first time).
d) Choose Window → Perspective → Open Perspective → Other.
The Open Perspectivedialog box displays.
e) Select the ABAP perspective from the list.
The ABAP Perspective now opens in the Eclipse editor.
352
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
f) Choose File → New → ABAP Project.
The New ABAP Projectdialog box displays.
g) In the New ABAP Projectdialog box, choose Browse.
The Select Existing Systemdialog box displays.
h) In the Select Existing Systemdialog box, select the correct system, for example ZME.
Choose Ok.
You are returned to the New ABAP Projectdialog box.
i) In the New ABAP Projectdialog box, choose Next.
j) Enter your Client, User, and Password as per the standard SAP logon. Choose Finish.
Define and Implement a Global Class
Create, define, and implement a global class for rooms. Use the quick fix functionality to add
the method implementations after you have defined the methods.
1. Create the global class ZCL_##_ROOM.
a) In the Eclipse Editor, choose File → New → ABAP Class.
The New ABAP Class dialog box displays.
b) In the New ABAP Class dialog box, ensure that your own project appears in the Project
field.
c) Next to the Package field, choose Browse and select your own package.
d) Enter the name of the new class and a description. Choose Next and Finish.
2. Define the following private instance attributes in the class ZCL_ROOM:
Table 5: Public Instance Attributes
Attribute Name
Type
MV_NUMBER
S_ROOM_NUMBER
MV_BEDS
I
a) See source code excerpt from the model solution.
3. Define the public instance constructor with the two import parameters IV_NUMBER and
IV_BEDS.
a) See source code excerpt from the model solution.
4. Define the public instance method GET_BEDS with returning parameter RV_BEDS.
a) See source code excerpt from the model solution.
5. Define a public instance event ROOM_CREATED with no parameters.
a) See source code excerpt from the model solution.
6. Use the Quick Fix functionality to add the method implementations. Then implement the
methods.
a) Place the cursor on the METHODS statement and press CTRL + 1.
The Quick Fix dialog box displays.
b) In the Quick Fix dialog box, choose Add 2 unimplemented methods.
c) Edit the method implementations, see source code extract from the model solution.
© Copyright. All rights reserved.
353
Unit 8: Global Classes in ABAP Development Tools
7. Save and activate the global class.
a) Save your program.
b) To activate your program, on the application toolbar, choose the Activate button.
Add Instances Rooms to the Hotel
Aggregate instances of ZCL_##_ROOM in your class ZCL_##_HOTEL.
Note:
Edit the class ZCL_##_HOTEL for all steps of this task.
1. Define the private instance attribute MT_ROOMS with type TABLE OF REF TO
ZCL_##_ROOM.
a) See source code excerpt from the model solution.
2. Define an event handler method for event ROOM_CREATED of class ZCL_##_ROOM.
a) See source code excerpt from the model solution.
3. Implement the event handler method for event ROOM_CREATED of class ZCL_##_ROOM
and append the sender to the list of rooms.
a) See source code excerpt from the model solution.
4. In the constructor of ZCL_##_HOTEL, register the handler FOR ALL INSTANCES of
ZCL_##_ROOM.
a) See source code excerpt from the model solution.
5. In the implementation of the DISPLAY_ATTRIBUTES method, define a local variable
LV_SUM_OF_BEDS of type i and a local reference variable LO_ROOM of type REF TO
ZCL_##_ROOM.
a) See source code excerpt from the model solution.
6. In the implementation of the DISPLAY_ATTRIBUTES method, edit the WRITE statement,
replace the MV_BEDS attribute with the local variable.
a) See source code excerpt from the model solution.
7. Before the WRITE statement, add a loop over the aggregated rooms. Call method
GET_BEDS for each room and add the result to LV_SUM_OF_BEDS.
a) See source code excerpt from the model solution.
8. Remove parameter IV_BEDS from the definition and implementation of the constructor of
ZCL_##_HOTEL. Delete unused attribute MV_BEDS.
a) See source code excerpt from the model solution.
9. Save and activate the global class.
a) Save your program.
b) To activate your program, on the application toolbar, choose the Activate button.
Create Instances of the Room Class
In your main program, create several instances of ZCL_##_ROOM to be aggregated in the
instance of your hotel class.
354
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
Note:
Edit your main program for all steps of this task.
1. Define a reference variable for instances of ZCL_##_ROOM called GO_ROOM with TYPE
REF TO ZCL_##_ROOM.
a) See source code excerpt from the model solution.
2. Create several instances of the class, using the reference variable GO_ROOM.
a) See source code excerpt from the model solution.
3. The rooms are to be aggregated into the hotel through the ROOM_CREATED event. Where
is the earliest point in your program where you can create the room instances?
After the instantiation of the hotel.
4. Save, activate, and run your program.
a) Save your program.
b) To activate your program, on the application toolbar, choose the Activate button.
c) To run your program, on the application toolbar, choose Run As → ABAP Application.
Solution: CL_ROOM
****************************************************
*
CLASS CL_ROOM DEFINITION
*
****************************************************
CLASS CL_ROOM DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS constructor
IMPORTING
iv_number TYPE s_room_number
iv_beds TYPE i.
METHODS get_beds RETURNING VALUE(rv_beds) TYPE i.
EVENTS room_created.
PRIVATE SECTION.
DATA mv_number TYPE s_room_number.
DATA mv_beds TYPE i.
ENDCLASS.
****************************************************
*
CLASS CL_ROOM IMPLEMENTATION
*
****************************************************
CLASS CL_ROOM IMPLEMENTATION.
METHOD constructor.
mv_beds = iv_beds.
© Copyright. All rights reserved.
355
Unit 8: Global Classes in ABAP Development Tools
mv_number = iv_number.
RAISE EVENT room_created.
ENDMETHOD.
METHOD get_beds.
rv_beds = mv_beds.
ENDMETHOD.
ENDCLASS.
Solution: CL_HOTEL3
****************************************************
*
CLASS CL_HOTEL3 DEFINITION
*
****************************************************
CLASS cl_hotel3 DEFINITION
PUBLIC
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_partner .
*
.
METHODS constructor
IMPORTING
iv_name TYPE string
iv_beds TYPE i
METHODS display_attributes .
METHODS on_room_created FOR EVENT room_created
OF cl_room
IMPORTING sender.
CLASS-METHODS display_n_o_hotels .
PRIVATE SECTION.
DATA mv_name TYPE string .
*
DATA mv_beds TYPE i .
DATA mt_rooms type table of ref to cl_room.
CLASS-DATA gv_n_o_hotels TYPE i .
CONSTANTS c_pos_1 TYPE i VALUE 30.
ENDCLASS.
****************************************************
*
CLASS CL_HOTEL3 IMPLEMENTATION
*
****************************************************
CLASS cl_hotel3 IMPLEMENTATION.
*
METHOD constructor .
mv_name = iv_name.
mv_beds = iv_beds.
ADD 1 TO gv_n_o_hotels.
RAISE EVENT if_partner~partner_created.
SET HANDLER on_room_created FOR ALL INSTANCES.
ENDMETHOD.
356
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
METHOD on_room_created.
APPEND sender TO mt_rooms.
ENDMETHOD.
*
METHOD display_attributes .
DATA lv_sum_of_beds type i.
DAtA lo_room type ref to cl_room.
ULINE.
WRITE:
/ 'Hotel'(001), AT c_pos_1 mv_name.
LOOP AT mt_rooms into lo_room.
v_sum_of_beds = lv_sum_of_beds + lo_room->get_beds( ).
ENDLOOP.
WRITE:
/ 'Total number of beds:'(002), AT c_pos_1 mv_beds.
/ 'Total number of beds:'(002), AT c_pos_1 lv_sum_of_beds.
ULINE.
ULINE.
SKIP.
ENDMETHOD.
METHOD display_n_o_hotels.
WRITE:
/ 'Total number of hotels:'(003), gv_n_o_hotels.
ENDMETHOD.
METHOD if_partner~display_partner.
me->display_attributes( ).
ENDMETHOD.
ENDCLASS.
Solution: SAPBC401_ADT_S1
REPORT sapbc401_adt_s1.
INCLUDE BC401_ADT_S1_AGENCY.
INCLUDE BC401_ADT_S1_CARRIER.
INCLUDE BC401_ADT_S1_RENTAL.
DATA:
go_room type ref to cl_room,
go_hotel TYPE REF TO cl_hotel3,
go_vehicle TYPE REF TO lcl_vehicle,
go_truck TYPE REF TO lcl_truck,
go_bus TYPE REF TO lcl_bus,
go_rental TYPE REF TO lcl_rental,
go_passenger TYPE REF TO lcl_passenger_plane,
go_cargo TYPE REF TO lcl_cargo_plane,
go_carrier TYPE REF TO lcl_carrier,
go_agency TYPE REF TO lcl_travel_agency.
START-OF-SELECTION.
*******************
******* create travel_agency **********************************
CREATE OBJECT go_agency
EXPORTING
iv_name = 'Travel&Smile Travel'.
******* create hotel ******************************************
CREATE OBJECT go_hotel
© Copyright. All rights reserved.
357
Unit 8: Global Classes in ABAP Development Tools
EXPORTING
iv_name = 'Sleep Well Hotel'.
* iv_beds = 345.
******* create room ******************************************
CREATE OBJECT go_room
EXPORTING
iv_number = '101'
iv_beds = 1.
CREATE OBJECT go_room
EXPORTING
iv_number = '102'
iv_beds = 2.
CREATE OBJECT go_room
EXPORTING
iv_number = '103'
iv_beds = 2.
CREATE OBJECT go_room
EXPORTING
iv_number = '201'
iv_beds = 3.
CREATE OBJECT go_room
EXPORTING
iv_number = '202'
iv_beds = 2.
358
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
Quick Fixes
Developers are often required to restructure source code to make it easy to understand, to
extend it, and also make it operate more efficiently. However, the consequences of
restructuring can lead to broken dependencies. Refactoring eliminates the need for the
tedious editing that is otherwise necessary to fix such restructuring problems.
Overview of Refactoring Options
●
Quick Fixes (for example, add missing method implementations)
●
Method Extraction
●
Deleting Unused Variables
●
Renaming (for example, rename an attribute, a method, a variable, an interface)
●
Changing Visibility (for example, turning local variables into attributes, making private
components public)
In Eclipse, Quick Fixes are shortcuts to complete tasks or resolve errors that are proposed
automatically by the editor. The class editor in ADT provides quick fixes for common editor
tasks.
Figure 138: Example of a Quick Fix
The key combination CTRL + 1 shows you available quick fixes in a dialog box. In a class, these
are as follows:
●
Add the implementation of a declared method.
●
Add all method implementations that are still missing (for example, all methods of an
interface).
●
Move a method to a different visibility section within the class.
© Copyright. All rights reserved.
359
Unit 8: Global Classes in ABAP Development Tools
Method Extraction
One important refactoring technique is method extraction. This involves moving a code block
to a new method and replacing the block with a call to that new method. To perform method
extraction, you must be editing a global or local ABAP class in a class pool, a program, or
another type of ABAP program. Your code must be free of syntax errors before you begin.
Note that method extraction is not supported in code outside of classes and that you can only
extract a method within the start and end area of another method.
Figure 139: Extracting a Method: Before
The figure, Extracting a Method: Before, shows two methods of the same class. They both
need the same existence check - although the processing that follows is different.
Extracting a Method: After
To increase coding reuse, you want to create a private method with the existence check, as
shown in the figure, Extracting a Method: After.
360
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
Figure 140: Extracting a Method: After
ADT supports the creation of method, CHECK_EXISTENCE, and its call in one of the original
methods by using the Extract Method function.
Deletion of Unused Variables
Another key refactoring technique is the deletion of the unused variables that can accumulate
in code over time. For example, perhaps you no longer need the code associated with a
variable and deleted the code but not the variable, or you may have extracted a method,
leaving behind data declarations that are outside of the scope of the extracted code.
Source Code Entity Name Changes
In object oriented programming, it sometimes becomes necessary to rename classes,
interfaces, or any of their components. Adjusting the coding lines referencing the entity then
becomes a tiresome and time consuming process, particularly if the entity is globally visible
and frequently reused. ADT allows you to rename the entity, and adjust all objects that use it.
© Copyright. All rights reserved.
361
Unit 8: Global Classes in ABAP Development Tools
362
© Copyright. All rights reserved.
Unit 8
Exercise 21
Use Refactoring Functions in ADT
Business Example
You need to make further changes to your hotel class, and would like to take advantage of the
refactoring functions in ABAP Development Tools to do this as efficiently as possible.
Note:
This exercise uses the global class ZCL_##_HOTEL completed in the previous
exercises. If not complete, copy the model solution from the previous exercise. In
the exercises for this course, when the input values include ##, replace ## with
your group number.
Template: CL_HOTEL3 (global class)
Solution: CL_HOTEL4 (global class)
Extract a Method to Output the Total Number of Beds
In your hotel class, use the extract method functionality of ABAP Development Tools to create
a private method that contains the calculation and the output of the total number of beds.
1. Define a private method DISPLAY_N_O_BEDS.
2. Implement the method DISPLAY_N_O_BEDS. Make sure that you have separate WRITE
statements for the output of the hotel name and the output of the total number of beds.
Move the loop over the aggregated rooms to immediately before the output of the total
number of rooms.
3. Extract a private method that contains the loop and the output of the total number of
beds.
Extract a Method to Calculate the Total Number of Beds
Use the extract method functionality of ABAP Development Tools to create a private method
that contains the calculation of the total number of beds, GET_N_O_BEDS.
1. Edit the DISPLAY_N_O_BEDS method of your class ZCL_##_HOTEL. Extract a private
method that contains the loop only.
Delete Unused Variables
Delete all unused variables, activate the class, and test your program.
1. Delete all unused variables from your hotel class.
2. Save, activate, and run your program.
Rename a Method
Use the Rename function of Eclipse, to rename method DISPLAY_PARTNER, of your interface
ZIF_##_PARTNER, to DISPLAY_PARTNER_ATTRIBUTES.
© Copyright. All rights reserved.
363
Unit 8: Global Classes in ABAP Development Tools
1. Change the name of method DISPLAY_PARTNER using the Rename function. Ensure that
all occurrences of the method name have changed.
2. Save and activate all affected objects.
3. Run your program.
364
© Copyright. All rights reserved.
Unit 8
Solution 21
Use Refactoring Functions in ADT
Business Example
You need to make further changes to your hotel class, and would like to take advantage of the
refactoring functions in ABAP Development Tools to do this as efficiently as possible.
Note:
This exercise uses the global class ZCL_##_HOTEL completed in the previous
exercises. If not complete, copy the model solution from the previous exercise. In
the exercises for this course, when the input values include ##, replace ## with
your group number.
Template: CL_HOTEL3 (global class)
Solution: CL_HOTEL4 (global class)
Extract a Method to Output the Total Number of Beds
In your hotel class, use the extract method functionality of ABAP Development Tools to create
a private method that contains the calculation and the output of the total number of beds.
1. Define a private method DISPLAY_N_O_BEDS.
a) See source code excerpt from the model solution.
2. Implement the method DISPLAY_N_O_BEDS. Make sure that you have separate WRITE
statements for the output of the hotel name and the output of the total number of beds.
Move the loop over the aggregated rooms to immediately before the output of the total
number of rooms.
a) See source code excerpt from the model solution.
3. Extract a private method that contains the loop and the output of the total number of
beds.
a) Select the LOOP ... ENDLOOP statement and the WRITE statement for the output of
LV_N_O_BEDS, then on the menu bar choose Source Code → Extract Method.
The Extract Method dialog box displays.
b) Enter the name of the new method. For the Visibility option, select the Private radio
button. Choose Next.
c) Accept all the default options and choose Next.
d) Analyze the suggested changes by comparing Original Source and Refactored Source.
Choose Finish.
Extract a Method to Calculate the Total Number of Beds
Use the extract method functionality of ABAP Development Tools to create a private method
that contains the calculation of the total number of beds, GET_N_O_BEDS.
© Copyright. All rights reserved.
365
Unit 8: Global Classes in ABAP Development Tools
1. Edit the DISPLAY_N_O_BEDS method of your class ZCL_##_HOTEL. Extract a private
method that contains the loop only.
a) Select the LOOP ... ENDLOOP statement and choose Source Code → Extract Method.
The Extract Method dialog box displays.
b) Enter the name of the new method. For the Visibility option, select the Private radio
button. Choose Next.
c) Accept all the default options and choose Next.
d) Analyze the suggested changes by comparing Original Source and Refactored Source.
e) Choose Finish.
f) For the refactored result, see source code extract for the model solution.
Delete Unused Variables
Delete all unused variables, activate the class, and test your program.
1. Delete all unused variables from your hotel class.
a) Choose Source Code → Delete unused variables (all).
2. Save, activate, and run your program.
a) Save your program.
b) To activate your program, on the application toolbar, choose the Activate button.
c) To run your program, on the application toolbar, choose Run As → ABAP Application.
Rename a Method
Use the Rename function of Eclipse, to rename method DISPLAY_PARTNER, of your interface
ZIF_##_PARTNER, to DISPLAY_PARTNER_ATTRIBUTES.
1. Change the name of method DISPLAY_PARTNER using the Rename function. Ensure that
all occurrences of the method name have changed.
a) Set the cursor on the method name and choose Source Code → Rename
The Rename Method dialog box displays.
b) In the Rename Method dialog box, enter DISPLAY_PARTNER_ATTRIBUTES. Choose
Next.
c) Analyze the list of affected objects and choose Next.
d) Analyze the changes that will be made by comparing the Original Source with the
Refactored Source. Choose Finish.
2. Save and activate all affected objects.
a) Save your program.
b) On the menu bar, choose Project → Activate Inactive ABAP Development Objects....
The Worklist of Inactive Objectsdialog box displays.
c) In the Worklist of Inactive Objectsdialog box, select all objects affected by the
renaming. Choose Activate.
3. Run your program.
a) To run your program, on the application toolbar, choose Run As → ABAP Application.
366
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
Solution: CL_HOTEL4
CLASS cl_hotel4 DEFINITION PUBLIC CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_partner.
.
METHODS constructor
IMPORTING
!iv_name TYPE string.
METHODS display_attributes.
METHODS on_room_created FOR EVENT room_created
OF cl_room
IMPORTING sender.
CLASS-METHODS display_n_o_hotels.
PRIVATE SECTION.
DATA mv_name TYPE string.
DATA mt_rooms TYPE TABLE OF REF TO cl_room.
METHODS display_n_o_beds.
METHODS get_n_o_rooms
RETURNING
VALUE(rv_sum_of_beds) TYPE i.
CLASS-DATA gv_n_o_hotels TYPE i.
CONSTANTS c_pos_1 TYPE i VALUE 30.
ENDCLASS.
CLASS cl_hotel4 IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
ADD 1 TO gv_n_o_hotels.
RAISE EVENT if_partner~partner_created.
SET HANDLER on_room_created FOR ALL INSTANCES.
ENDMETHOD.
METHOD display_attributes.
ULINE.
WRITE:
/ 'Hotel'(001), AT c_pos_1 mv_name.
display_n_o_beds( ).
ULINE.
SKIP.
ENDMETHOD.
...
METHOD display_n_o_beds.
DATA lv_sum_of_beds TYPE i.
lv_sum_of_beds = get_n_o_rooms( ).
© Copyright. All rights reserved.
367
Unit 8: Global Classes in ABAP Development Tools
*
WRITE:
/ 'Total number of beds:'(002), AT c_pos_1 mv_beds.
/ 'Total number of beds:'(002), AT c_pos_1 lv_sum_of_beds.
ULINE.
ENDMETHOD.
METHOD get_n_o_rooms.
DATA lo_room TYPE REF TO cl_room.
LOOP AT mt_rooms INTO lo_room.
rv_sum_of_beds = rv_sum_of_beds + lo_room->get_beds( ).
ENDLOOP.
ENDMETHOD.
ENDCLASS.
368
© Copyright. All rights reserved.
Lesson: Developing Eclipse-Based ABAP Programs
LESSON SUMMARY
You should now be able to:
●
Implement Eclipse-based ABAP development
●
Use quick fixes and refactoring
© Copyright. All rights reserved.
369
Unit 8: Global Classes in ABAP Development Tools
370
© Copyright. All rights reserved.
Unit 8
Learning Assessment
1. When you work with ADT, you log onto the ABAP back-end system and remain logged on
for your entire session.
Determine whether this statement is true or false.
X
True
X
False
2. ADT contains native Eclipse editors for which kinds of repository objects?
Choose the correct answers.
X
A ABAP programs
X
B Data elements
X
C ABAP classes
X
D Packages
X
E Text elements
3. You are creating an ABAP class in ADT and have just written the definition of a method in
the public section of the class definition. You press CTRL + 1 to see the available quick
fixes. Which fixes are available?
Choose the correct answers.
X
A Add the implementation of the method
X
B Move the method definition to the protected or private section
X
C Delete the method
© Copyright. All rights reserved.
371
Unit 8
Learning Assessment - Answers
1. When you work with ADT, you log onto the ABAP back-end system and remain logged on
for your entire session.
Determine whether this statement is true or false.
X
True
X
False
2. ADT contains native Eclipse editors for which kinds of repository objects?
Choose the correct answers.
X
A ABAP programs
X
B Data elements
X
C ABAP classes
X
D Packages
X
E Text elements
3. You are creating an ABAP class in ADT and have just written the definition of a method in
the public section of the class definition. You press CTRL + 1 to see the available quick
fixes. Which fixes are available?
Choose the correct answers.
372
X
A Add the implementation of the method
X
B Move the method definition to the protected or private section
X
C Delete the method
© Copyright. All rights reserved.
UNIT 9
Class-Based Exceptions
Lesson 1
Explaining Class-Based Exceptions
374
Lesson 2
Defining and Raising Exceptions
Exercise 22: Implement Class-Based Exceptions
380
389
Lesson 3
Implementing Advanced Exception Handling Techniques
Exercise 23: Map Exceptions to Each Other
403
411
UNIT OBJECTIVES
●
Explain class-based exceptions
●
Handle class-based exceptions
●
Debug class-based exceptions
●
Define global exception classes
●
Raise class-based exceptions
●
Propagate exceptions
●
Explain the hierarchy of predefined exception classes
●
Explain different ways of handling an exception
●
Retry after exceptions
●
Implement resumable exceptions
●
Map exceptions
© Copyright. All rights reserved.
373
Unit 9
Lesson 1
Explaining Class-Based Exceptions
LESSON OVERVIEW
This lesson explains how to handle and debug class-based exceptions.
Business Example
You must use the new exceptions concept in your ABAP Object programs. For this reason,
you require the following knowledge:
●
An understanding of class-based exceptions
●
An understanding of how to handle class-based exceptions
●
An understanding of how to debug class-based exceptions
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Explain class-based exceptions
●
Handle class-based exceptions
●
Debug class-based exceptions
Class-Based Exceptions
An exception is a situation that arises while a program is being executed during which there is
no point to continue the normal program flow. SAP NetWeaver Application Server (SAP
NetWeaver AS) S 6.10 introduced a new ABAP Objects exception concept that exists parallel
to the existing concept based on sy-subrc. Exceptions and exception handling are now based
on classes. This new ABAP Objects exception concept enhanced the classic way of handling
exception using sy-subrc.
Hint:
Note that the use of class-based exceptions is not limited to object-oriented
contexts. Class-based exceptions can be raised and handled in all processing
blocks. In particular, all previously catchable runtime errors can be handled as
class-based exceptions.
374
© Copyright. All rights reserved.
Lesson: Explaining Class-Based Exceptions
Figure 141: An Overview of the Class-Based Exception Concept
In the new exception concept, an exception is represented by an exception object. An
exception object is an instance of an exception class. The attribute values of the exception
object contain information about the respective error situation. Raising a class-based
exception means instantiating an exception class and setting the attributes. Handling a classbased exception involves evaluating the exception object and its attribute values.
Class-based exceptions are raised either by the RAISE EXCEPTION statement or by the
runtime environment. You catch and handle class-based exceptions with the
TRY...CATCH...ENDTRY structure.
© Copyright. All rights reserved.
375
Unit 9: Class-Based Exceptions
Hierarchy of Exception Classes
Figure 142: Exception Classes – The Inheritance Hierarchy
You can define your own exception classes, but the system already includes a range of
predefined exception classes – particularly for exceptions in the runtime environment. You
can create exception classes globally in the Class Builder, but you can also define local
exception classes within a program or global class.
The names of global exception classes always start with <namespace>CX_. Those global
exception classes that the runtime environment uses start with CX_SY_. We recommend that
you start the names of local exception classes with LCX_.
All exception classes are derived from one exception class, CX_ROOT. Therefore, you can
generically access any exception object through a reference variable, REF TO CX_ROOT.
However, a new exception class is not allowed to inherit directly from CX_ROOT, derive any
new exception class directly or indirectly from one of the subclasses CX_ROOT CX_NO_CHECK, CX_DYNAMIC_CHECK, or CX_STATIC_CHECK.
Through this, all exception classes are subdivided into three groups. Depending on the group
to which a given exception belongs, the exception is treated differently by syntax check and
runtime environment. The default group is CX_STATIC_CHECK, which ensures maximum
syntax check and program stability. Use the other groups only in special cases.
The GET_SOURCE_POSITION method returns the name of the main program or include
program and also the line number in the source code where the exception occurs. The
GET_TEXT method returns an exception text in the form of a string. This method is not
defined in CX-ROOT directly but in interface IF_MESSAGE, which is implemented by CXROOT.
376
© Copyright. All rights reserved.
Lesson: Explaining Class-Based Exceptions
Class-Based Exception Handling
Figure 143: Structure of a TRY-ENDTRY Block
You can handle an exception if the statement that raised it is enclosed inside a TRY-ENDTRY
control structure. You handle the exception using the CATCH statement in the TRY-ENDTRY
structure.
The TRY block contains the statements for which the exceptions need to be handled. A
CATCH block contains the exception handler, which is executed if a specified exception has
occurred in the associated TRY block.
Like all control structures in ABAP Objects, you can nest TRY-ENDTRY structures to any
depth. In particular, the TRY block, the CATCH block, and the CLEANUP block can contain
complete TRY-ENDTRY structures themselves.
Specify any number of exception classes in the CATCH statement. In this way, you define an
exception handler for all these exception classes and their subclasses.
If an exception occurs, the system searches for a matching CATCH statement in the TRYENDTRY structure that immediately surrounds the statement. It searches through the
CATCH blocks for the relevant exception class or the superclasses from the inheritance
hierarchy. If any of the relevant exception classes is found, the program navigates directly to
the handler.
If the system does not find a matching CATCH statement, it gradually searches outwards in
the surrounding TRY-ENDTRY structures. If no handler can be found within the same
procedure, the system tries to propagate the exception to the calling program. This process
will be discussed in more detail later.
If a TRY-ENDTRY structure contains a CLEANUP block, this block is executed when the TRYENDTRY structure is exited because the system cannot find a handler within the TRYENDTRY structure itself but instead in a surrounding TRY-ENDTRY structure or in a calling
program.
© Copyright. All rights reserved.
377
Unit 9: Class-Based Exceptions
Example Syntax for Handling Predefined Exceptions
Figure 144: Example Syntax for Handling Predefined Exceptions
The figure, Example Syntax for Handling Predefined Exceptions, shows an example of syntax
for handling predefined exceptions.
To analyze the exception object in an exception handler, use the CATCH statement in the
form CATCH ... INTO ... You have to specify a suitably typed object reference after the
optional addition INTO. The reference can be a reference either to the exception class itself or
to any of its superclasses. Just before the system executes CATCH block, the system fills the
reference variable so that it points to the exception object describing the present error
situation.
If the value range for data type I is exceeded in the calculation, the runtime system raises
exception CX_SY_ARITHMETIC_OVERFLOW. This exception is handled in the implemented
CATCH block. The reference to the appropriate instance is stored in data object GO_EXC in
the example. The handler can access the instance’s exception text using the functional
method GET_TEXT. The exception text is stored in the data object GV_TEXT with the type
STRING and then displayed as an information message.
You can access any other public component of the exception object during exception
handling depending on the static type of the reference variable. In the example above, the
reference variable is typed as REF TO CX_ROOT, which restricts access to those components
defined in CX_ROOT. To access the more-specific components of the exception object, you
need a more-specific type reference variable type. You can also use the superclass
CX_SY_ARITHMETIC_ERROR and the super-superclass CX_DYNAMIC_CHECK to access the
specific components of the exception object.
The ABAP keyword documentationfor each statement lists the classes whose exceptions may
occur when that statement is executed.
378
© Copyright. All rights reserved.
Lesson: Explaining Class-Based Exceptions
Class-Based Exceptions in the Debugger
Figure 145: Class-Based Exceptions in Debugging Mode
If an exception is raised, the system displays name of the exception class in the Exception
Raised field in debugging mode.
If a CATCH block catches the exception a success message displays. The pointer for the
current statement then moves to this CATCH block.
Two buttons appear if an exception occurs. Use the buttons to analyze the exception object
and to navigate to the point in the source code where the exception occurred respectively.
Hint:
For performance reasons, the system does not actually create exception objects
if the INTO addition is missing from the respective CATCH statement. In such
cases, the Last Exception Objectbutton normally does not appear.
To set the ABAP Debugger to always create the exception object, choose the
respective option in the debugger settings.
LESSON SUMMARY
You should now be able to:
●
Explain class-based exceptions
●
Handle class-based exceptions
●
Debug class-based exceptions
© Copyright. All rights reserved.
379
Unit 9
Lesson 2
Defining and Raising Exceptions
LESSON OVERVIEW
This lesson explains how to define and raise global exception classes.
Business Example
You need to define global exception classes for your ABAP Objects programs. For this reason,
you require the following knowledge:
●
An understanding of the definition of global exception classes
●
An understanding of how to raise class-based exceptions
●
An understanding of how to implement exception propagation
LESSON OBJECTIVES
After completing this lesson, you will be able to:
380
●
Define global exception classes
●
Raise class-based exceptions
●
Propagate exceptions
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
Definition of Global Exception Classes
Figure 146: Creating Global Exception Classes
You use Class Builder to create a global class as described in SAP Library. When you enter the
name of global class, use the prefix CX_. Choose the Exception Class option as the class type.
Note:
As of SAP NetWeaver Application Server 6.40 (SAP NetWeaver AS 6.40), there is
a message class checkbox that you may select when you create the class. This
option allows the text from the exception classes to be reused from any message
class, the text of which is stored in table T100. You cannot mix text from message
classes and the OTR in one exception class.
In releases before SAP NetWeaver AS 6.40, exception texts were stored solely in
the Online Text Repository (OTR).
When you create an exception class, do not change the default entry for Inherits
from unless you are fully aware of the consequences of making the change.
Define additional attributes in your exception class as necessary (for example, for generic
extensions to exception texts).
© Copyright. All rights reserved.
381
Unit 9: Class-Based Exceptions
Hint:
If such an attribute is public, the Class Builder automatically adjusts the instance
constructor of the exception class.
A new input parameter is generated and a value can be set for this attribute when
raising the exception. The import parameter is generated with the same name as
the attribute. By default, the parameter is optional. You may declare it
mandatory by editing the constructor’s signature.
Define Variable Exception Texts
Figure 147: Define Variable Exception Texts
Save as many exception texts as you need. When you save exception texts, you can insert
attributes as parameters in the static text using the form &<attribute_name>&.
Note:
For the first text you create, always use the predefined static constant as an ID.
The constant always has the same name as the exception class itself. If the raiser
of the exception does not specify a text when the exception is raised, the system
uses the text with this ID.
You define other IDs for all other texts. Class Builder then generates identically named static
constants automatically. When the exception is raised, pass one of these constants to import
parameter TEXTID to specify the appropriate text for the exception instance.
382
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
Note:
In releases before SAP NW AS 6.40, exception texts for global exception classes
and their translations were stored in OTR. You can assign several texts to a single
class. You assign a text to an exception using the TEXTID attribute, which contains
the globally unique ID of the text object in OTR in an instance at runtime. The
GET_TEXT method then exports this text, replaces any text parameters with the
contents of the relevant attributes as required, and returns the text as a character
string.
Activate the exception class after filling in the exception texts.
To Define Global Exception Classes
1. In the Class Builder, in the unnamed dropdown list on the left of the screen, choose Class/
Interface.
2. In the unnamed field, enter the new exception class name, use the prefix ZCX_. Press
Enter.
3. To create the class, choose Yes.
A Create Class dialog box displays.
4. Select the Exception Class radio button, and, if you want the exception texts to come from
an existing message class, choose the With Message Class checkbox.
5. Enter a short description.
6. Do not change the default Superclass CX_STATIC_CHECK. Choose Save.
The Create Object Directory Entrydialog box displays.
7. In the Create Object Directory Entrydialog box, enter your package name and choose
Save.
A Prompt for transportable Workbenchrequest dialog box displays.
8. In the Prompt for transportable Workbenchdialog box, accept the defaults and choose
Continue.
9. Define additional attributes in your exception class if necessary (for example, to use in the
exception texts).
Note:
If these attributes are public, the Class Builder automatically adjusts the
instance constructor of the exception class: A new input parameter is
generated so that a value can be provided for this attribute when raising the
exception. The import parameter is generated with the same name as the
attribute. By default the parameter is optional. You may declare it as
mandatory by editing the constructor’s signature.
10. Choose the Texts tab in the Class Builder, and create as many exception texts as you
need. When you do so, you can insert your attributes as parameters in the static text in the
form &<ATTRIBUTE_NAME>&.
© Copyright. All rights reserved.
383
Unit 9: Class-Based Exceptions
Note:
For the first text you create, always use the predefined static constant as an
ID. It always has the same name as the exception class itself. If no text is
specified explicitly when the exception is raised, the text with this ID is used.
For all other texts, you define other IDs. The Class Builder then generates
identically named static constants automatically. When the exception is raised,
you pass one of these constants to the import parameter TEXTID, to specify
the appropriate text for the exception instance.
Use of the RAISE EXCEPTION Statement
Figure 148: Variants of Statement RAISE EXCEPTION
The figure Variants of Statement RAISE EXCEPTION, shows examples for statement RAISE
EXCEPTION.
Raising class-based exceptions is done using the RAISE EXCEPTION statement. There are
two variants of the statement.
Variants of Statement RAISE EXCEPTION ...
RAISE EXCEPTION TYPE <exception_class> [EXPORTING ...].
This statement creates a new exception object that is an instance of the <exception_class>
class.
RAISE EXCEPTION <object_ref>.
This statement uses an existing exception object that the one <object_ref> points to.
The exception object was either created directly using a CREATE OBJECT statement or
caught in a previous CATCH ... INTO ...statement.
384
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
When using the first variant, it is possible to provide values for the constructor parameters
using the EXPORTING addition. One of these parameters is used to set the exception text in
the new exception object.
Exception Texts
Figure 149: Setting the Exception Text
All exception classes offer an optional parameter TEXTID in their constructors. Use this
parameter if more than one message text is available in the exception class and you do not
want to raise the exception with the default text.
For each text defined on the Texts tab page, the Class Builder generates a public constant of
the same name. Constants may also be inherited from the superclasses of the exception
class.
By default, the system raises an exception with the text that has the same name as the
exception class. To raise the exception with another text, use the corresponding constant as
the actual parameter for constructor parameter TEXTID.
Note:
The type of the constants and parameter TEXTID in the constructor is determined
by whether or not the exception class was created with the With message class
flag. If the exception class still uses OTR texts, the constants are of type CHAR and
contain a technical ID of the OTR text. If the exception class uses a message class,
the constants are structures containing the name of the message class, the
message number.
© Copyright. All rights reserved.
385
Unit 9: Class-Based Exceptions
Exception Propagation
Figure 150: Propagating Class-Based Exceptions
The handling of exceptions that occur within procedures does not have to lie within the same
procedure. Instead, the procedure can propagate the exception to its caller. The caller can
then handle the exception or propagate it to its own caller. The highest levels to which an
exception can be propagated are processing blocks without local data areas, that is, event
blocks or dialog modules. These processing blocks have to handle the propagated exceptions.
Otherwise, a runtime error occurs. The same is true for exceptions raised within such
processing blocks.
To propagate an exception from a procedure, you generally use the RAISING addition when
you define the procedure interface. In methods of local classes and subroutines, specify the
RAISING addition directly when you are defining the procedure. For example:
METHODS meth_name ... RAISING cx_... cx_... or FORM subr_name ... RAISING cx_... cx_....
The RAISING addition is followed by a list of the exception classes whose instances are to be
propagated. In methods of global classes, enter exception classes whose instances are to be
propagated into the exception table of the method in the Class Builder. You also need to set
the Exception Class flag for each exception table. The process is similar for function modules.
To set the indicator in Function Builder, choose the Exceptions tab.
Hint:
A single method, subroutine, or function module can raise only one type of
exception, that is, either class-based or conventional.
386
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
Propagating Exceptions Over Several Hierarchy – Levels
Figure 151: Propagating Exceptions Over Several Hierarchy – Levels
Propagation of class-based exception does not require that the calling method actually
handles the exception. The caller may pass the exception to its own caller even without
handling it.
In the example, the constructor propagates the CX_EXC exception raised by the
GET_TECH_ATTR method. When the error occurs and the program raises the exception, the
program flow jumps directly to the CATCH block in the main program.
Note:
If the constructor implements the optional CLEANUP block, the system executes
this block before the CATCH block of the main program.
© Copyright. All rights reserved.
387
Unit 9: Class-Based Exceptions
388
© Copyright. All rights reserved.
Unit 9
Exercise 22
Implement Class-Based Exceptions
Business Example
Your program uses the class-based exception concept if an invalid plane type is provided
when creating an airplane instance.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_GCL_S2
Solutions:
●
SAPBC401_EXC_S1 (Main program)
●
CX_INVALID_PLANETYPE (exception class)
Create a Global Exception Class
Create a global exception class for an invalid airplane type.
1. Create a global exception class called ZCX_##_INVALID_PLANETYPE.
Hint:
You want the syntax check to ensure that exceptions based on this class are
either handled directly or propagated. Choose the superclass accordingly. In
the exception class, use texts from a message class instead of freely defined
texts.
2. Add an attribute for the airplane type and assign the type S_PLANETYE to it. Make sure
that a corresponding parameter is defined in the signature of the constructor.
Hint:
You cannot define the constructor of an exception class directly. If you define
the attribute as public, a corresponding import parameter is added to the
constructor by the framework.
3. Create a default error message. Include a placeholder in the message text so that it can be
enhanced dynamically to include the airplane type.
© Copyright. All rights reserved.
389
Unit 9: Class-Based Exceptions
Hint:
You can define your own message class and message or use message 020
from message class BC401.
Raise an Exception With Your Own Exception Type
Raise the new exception in method GET_TECHNICAL_ATTRIBUTES of your local class
LCL_AIRPLANE.
1. In the main program, edit the definition of local class LCL_AIRPLANE. Remove the
classical, non class-based exception WRONG_PLANETYPE from the signature of method
GET_TECHNICAL_ATTRIBUTES and replace it with your new class-based exception
ZCX_##_INVALID_PLANETYPE.
2. Edit the implementation of method GET_TECHNICAL_ATTRIBUTES and raise the classbased exception instead of the classical exception. Ensure that the wrong plane type value
is handed over to the constructor and stored in the exception object.
Propagate the Raised Exception
Propagate the class-based exception explicitly through the entire call hierarchy so that you
must handle it only once in the main program.
1. Edit the definition of local class LCL_AIRPLANE. Remove the classical, non class-based
exception WRONG_PLANETYPE from the signature of method CONSTRUCTOR and
replace it with your new class-based exception, ZCX_##_INVALID_PLANETYPE.
2. Edit the implementation of the constructor of local class LCL_AIRPLANE. While calling
method GET_TECHNICAL_ATTRIBUTES, remove the handling of classical exception
WRONG_PLANETYPE.
3. Why is it not necessary to handle the class-based exception
ZCX_##_INVALID_PLANETYPE here?
4. Edit the definition of local class LCL_PASSENGER_PLANE. Remove the classical, non
class-based exception WRONG_PLANETYPE from the signature of the CONSTRUCTOR
method and replace it with your new class-based exception
ZCX_##_INVALID_PLANETYPE.
5. Edit the implementation of the constructor of local class LCL_PASSENGER_PLANE. In the
call of SUPER->CONSTRUCTOR, remove the handling of classical exception
WRONG_PLANETYPE.
6. Repeat the previous steps with local class LCL_CARGO_PLANE.
Handle the Class-Based Exception
Handle the raised exception in the main program whenever an airplane object is created.
1. Define a global reference variable for this purpose (suggested name:
GO_INV_PLANETYPE) and type it with your exception class
ZCX_##_INVALID_PLANETYPE.
390
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
2. In the CREATE OBJECT statement for airplanes (instances of LCL_AIRPLANE,
LCL_PASSENGER_PLANE, and LCL_CARGO_PLANE), remove the handling of the
classical, non class-based exception WRONG_PLANETYPE.
3. Surround each CREATE OBJECT statement for airplanes with a TRY-ENDTRY structure.
Add a CATCH block for your exception ZCX_##_INVALID_PLANETYPE. In the case of an
exception, let reference variable GO_INV_PLANETYPE point to the exception object.
4. Read the error text from the exception object and output it to the ABAP list.
Hint:
It is not possible to use the result of functional methods directly in the WRITE
statement. You need to define a variable to store the text (suggested name:
GV_TEXT with data type STRING).
5. Save, check, and activate the program.
6. Run your program. For test purposes, create an airplane with a wrong plane type and
debug the propagation of the exception.
© Copyright. All rights reserved.
391
Unit 9
Solution 22
Implement Class-Based Exceptions
Business Example
Your program uses the class-based exception concept if an invalid plane type is provided
when creating an airplane instance.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_GCL_S2
Solutions:
●
SAPBC401_EXC_S1 (Main program)
●
CX_INVALID_PLANETYPE (exception class)
Create a Global Exception Class
Create a global exception class for an invalid airplane type.
1. Create a global exception class called ZCX_##_INVALID_PLANETYPE.
Hint:
You want the syntax check to ensure that exceptions based on this class are
either handled directly or propagated. Choose the superclass accordingly. In
the exception class, use texts from a message class instead of freely defined
texts.
a) In the unnamed dropdown list on the left of the screen, choose Class /Interface,
specify the name of the package ZCX_##_INVALID_PLANETYPE, and press Enter.
A Create Class/Interfacedialog box displays.
b) To create the Exception Class, choose Yes.
A Create Class dialog box displays.
c) In the Create Class dialog box, select Exception Class radio button and select the With
Message Class checkbox. Enter a short description and choose Save.
A Create Object Directory Entrydialog box displays.
d) In the Create Object Directory Entrydialog box, enter your package name and choose
Save.
A Prompt for transportable Workbench requestdialog box displays.
392
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
e) In the Prompt for transportable Workbench requestdialog box, accept the defaults and
choose Continue.
2. Add an attribute for the airplane type and assign the type S_PLANETYE to it. Make sure
that a corresponding parameter is defined in the signature of the constructor.
Hint:
You cannot define the constructor of an exception class directly. If you define
the attribute as public, a corresponding import parameter is added to the
constructor by the framework.
a) On the Attributes tab page, enter the attribute name and type and choose the visibility.
3. Create a default error message. Include a placeholder in the message text so that it can be
enhanced dynamically to include the airplane type.
Hint:
You can define your own message class and message or use message 020
from message class BC401.
a) On the Texts tab page, select the default text and choose Message Text.
b) Enter the message class and message number in the relevant fields. In the Attr. 1 field,
use the value that helps to choose attribute PLANETYPE.
Raise an Exception With Your Own Exception Type
Raise the new exception in method GET_TECHNICAL_ATTRIBUTES of your local class
LCL_AIRPLANE.
1. In the main program, edit the definition of local class LCL_AIRPLANE. Remove the
classical, non class-based exception WRONG_PLANETYPE from the signature of method
GET_TECHNICAL_ATTRIBUTES and replace it with your new class-based exception
ZCX_##_INVALID_PLANETYPE.
a) See the source code extract from the model solution.
2. Edit the implementation of method GET_TECHNICAL_ATTRIBUTES and raise the classbased exception instead of the classical exception. Ensure that the wrong plane type value
is handed over to the constructor and stored in the exception object.
a) See the source code extract from the model solution.
Propagate the Raised Exception
Propagate the class-based exception explicitly through the entire call hierarchy so that you
must handle it only once in the main program.
1. Edit the definition of local class LCL_AIRPLANE. Remove the classical, non class-based
exception WRONG_PLANETYPE from the signature of method CONSTRUCTOR and
replace it with your new class-based exception, ZCX_##_INVALID_PLANETYPE.
a) See the source code extract from the model solution.
2. Edit the implementation of the constructor of local class LCL_AIRPLANE. While calling
method GET_TECHNICAL_ATTRIBUTES, remove the handling of classical exception
WRONG_PLANETYPE.
a) See the source code extract from the model solution.
© Copyright. All rights reserved.
393
Unit 9: Class-Based Exceptions
3. Why is it not necessary to handle the class-based exception
ZCX_##_INVALID_PLANETYPE here?
It is because this exception is propagated in the signature of the constructor of
LCL_AIRPLANE.
4. Edit the definition of local class LCL_PASSENGER_PLANE. Remove the classical, non
class-based exception WRONG_PLANETYPE from the signature of the CONSTRUCTOR
method and replace it with your new class-based exception
ZCX_##_INVALID_PLANETYPE.
a) See the source code extract from the model solution.
5. Edit the implementation of the constructor of local class LCL_PASSENGER_PLANE. In the
call of SUPER->CONSTRUCTOR, remove the handling of classical exception
WRONG_PLANETYPE.
a) See the source code extract from the model solution.
6. Repeat the previous steps with local class LCL_CARGO_PLANE.
a) See the source code extract from the model solution.
Handle the Class-Based Exception
Handle the raised exception in the main program whenever an airplane object is created.
1. Define a global reference variable for this purpose (suggested name:
GO_INV_PLANETYPE) and type it with your exception class
ZCX_##_INVALID_PLANETYPE.
a) See the source code extract from the model solution.
2. In the CREATE OBJECT statement for airplanes (instances of LCL_AIRPLANE,
LCL_PASSENGER_PLANE, and LCL_CARGO_PLANE), remove the handling of the
classical, non class-based exception WRONG_PLANETYPE.
a) See the source code extract from the model solution.
3. Surround each CREATE OBJECT statement for airplanes with a TRY-ENDTRY structure.
Add a CATCH block for your exception ZCX_##_INVALID_PLANETYPE. In the case of an
exception, let reference variable GO_INV_PLANETYPE point to the exception object.
a) See the source code extract from the model solution.
4. Read the error text from the exception object and output it to the ABAP list.
Hint:
It is not possible to use the result of functional methods directly in the WRITE
statement. You need to define a variable to store the text (suggested name:
GV_TEXT with data type STRING).
a) See the source code extract from the model solution.
5. Save, check, and activate the program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
394
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
6. Run your program. For test purposes, create an airplane with a wrong plane type and
debug the propagation of the exception.
a) To run your program, on the application toolbar, choose the Direct Processingbutton.
Include: BC401_EXC_S1_CARRIER
*------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*------------------------------------------------*
CLASS lcl_airplane DEFINITION.
PUBLIC SECTION.
*
*
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
EXCEPTIONS
wrong_planetype,
RAISING
cx_invalid_planetype,
display_attributes.
CLASS-METHODS:
display_n_o_airplanes,
class_constructor.
EVENTS:
airplane_created.
PROTECTED SECTION.
CONSTANTS:
c_pos_1 TYPE i VALUE 30.
PRIVATE SECTION.
TYPES:
ty_planetypes TYPE STANDARD TABLE OF saplane
WITH NON-UNIQUE KEY planetype.
DATA:
mv_name
mv_planetype
mv_weight
mv_tankcap
TYPE
TYPE
TYPE
TYPE
string,
saplane-planetype,
saplane-weight,
saplane-tankcap.
CLASS-DATA:
gv_n_o_airplanes TYPE i,
gt_planetypes
TYPE ty_planetypes.
*
*
CLASS-METHODS:
get_technical_attributes
IMPORTING
iv_type
TYPE saplane-planetype
EXPORTING
ev_weight
TYPE saplane-weight
ev_tankcap TYPE saplane-tankcap
EXCEPTIONS
wrong_planetype.
© Copyright. All rights reserved.
395
Unit 9: Class-Based Exceptions
RAISING cx_invalid_planetype.
ENDCLASS.
"lcl_airplane DEFINITION
*-------------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
METHOD class_constructor.
SELECT * FROM saplane INTO TABLE gt_planetypes.
ENDMETHOD.
"class_constructor
METHOD constructor.
mv_name
= iv_name.
mv_planetype
= iv_planetype.
get_technical_attributes(
EXPORTING
iv_type = iv_planetype
IMPORTING
ev_weight = mv_weight
ev_tankcap = mv_tankcap ).
gv_n_o_airplanes = gv_n_o_airplanes + 1.
RAISE EVENT airplane_created.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
get_technical_attributes(
EXPORTING
iv_type = iv_planetype
IMPORTING
ev_weight = mv_weight
ev_tankcap = mv_tankcap
EXCEPTIONS
wrong_planetype = 1 ).
IF sy-subrc <> 0.
RAISE wrong_planetype.
ELSE.
gv_n_o_airplanes = gv_n_o_airplanes + 1.
RAISE EVENT airplane_created.
ENDIF.
ENDMETHOD.
"constructor
METHOD display_attributes.
WRITE:
/ icon_ws_plane AS ICON,
/ 'Name of Airplane'(001) ,
/ 'Type of Airplane:'(002),
/ 'Weight:'(003),
LEFT-JUSTIFIED,
/ 'Tank capacity:'(004),
LEFT-JUSTIFIED.
ENDMETHOD.
AT c_pos_1 mv_name,
AT c_pos_1 mv_planetype,
AT c_pos_1 mv_weight
AT c_pos_1 mv_tankcap
"display_attributes
METHOD display_n_o_airplanes.
SKIP.
WRITE:
/ 'Number of airplanes:'(ca1),
AT c_pos_1 gv_n_o_airplanes LEFT-JUSTIFIED.
ENDMETHOD.
"display_n_o_airplanes
396
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
METHOD get_technical_attributes.
DATA: ls_planetype TYPE saplane.
READ TABLE gt_planetypes INTO ls_planetype
WITH TABLE KEY planetype = iv_type
TRANSPORTING weight tankcap.
IF sy-subrc = 0.
ev_weight = ls_planetype-weight.
ev_tankcap = ls_planetype-tankcap.
ELSE.
*
RAISE wrong_planetype.
RAISE EXCEPTION TYPE cx_invalid_planetype
EXPORTING
planetype = iv_type.
ENDIF.
ENDMETHOD.
"get_technical_attributes
ENDCLASS.
"lcl_airplane IMPLEMENTATION
*-------------------------------------------------*
*
CLASS lcl_cargo_plane DEFINITION
*---------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING FROM lcl_airplane.
PUBLIC SECTION.
*
*
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
iv_cargo
TYPE s_plan_car
RAISING
cx_invalid_planetype,
EXCEPTIONS
wrong_planetype,
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:
mv_cargo TYPE s_plan_car.
ENDCLASS.
"lcl_cargo_plane DEFINITION
*-----------------------------------------------*
*
CLASS lcl_cargo_plane IMPLEMENTATION
*-----------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
METHOD constructor.
super->constructor(
EXPORTING
iv_name
= iv_name
iv_planetype = iv_planetype ).
*
EXCEPTIONS
*
wrong_planetype = 1 ).
*
IF sy-subrc <> 0.
© Copyright. All rights reserved.
397
Unit 9: Class-Based Exceptions
*
*
RAISE wrong_planetype.
ENDIF.
mv_cargo = iv_cargo.
ENDMETHOD.
"constructor
METHOD display_attributes.
super->display_attributes( ).
WRITE:
/ 'Max Cargo:'(005), AT c_pos_1 mv_cargo
LEFT-JUSTIFIED.
ULINE.
ENDMETHOD.
"display_attributes
ENDCLASS.
"lcl_cargo_plane IMPLEMENTATION
*------------------------------------------------*
*
CLASS lcl_passenger_plane DEFINITION
*------------------------------------------------*
CLASS lcl_passenger_plane DEFINITION INHERITING FROM lcl_airplane.
PUBLIC SECTION.
*
*
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
iv_seats
TYPE s_seatsmax
EXCEPTIONS
wrong_planetype
RAISING
cx_invalid_planetype,
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:
mv_seats TYPE s_seatsmax.
ENDCLASS.
"lcl_passenger_plane DEFINITION
*-----------------------------------------------*
*
CLASS lcl_passenger_plane IMPLEMENTATION
*-----------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
METHOD constructor.
super->constructor(
EXPORTING
iv_name
= iv_name
iv_planetype = iv_planetype ).
*
*
*
*
*
EXCEPTIONS
wrong_planetype = 1 ).
IF sy-subrc <> 0.
RAISE wrong_planetype.
ENDIF.
mv_seats = iv_seats.
ENDMETHOD.
"constructor
398
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
METHOD display_attributes.
super->display_attributes( ).
WRITE:
/ 'Max Seats:'(006), AT c_pos_1 mv_seats
LEFT-JUSTIFIED.
ULINE.
ENDMETHOD.
"display_attributes
ENDCLASS.
"lcl_passenger_plane IMPLEMENTATION
*---------------------------------------------------*
*
CLASS lcl_carrier DEFINITION
*---------------------------------------------------*
CLASS lcl_carrier DEFINITION.
...
ENDCLASS.
"lcl_carrier DEFINITION
*---------------------------------------------------*
*
CLASS lcl_carrier IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
...
ENDCLASS.
"lcl_carrier IMPLEMENTATION
Main program: SAPBC401_EXC_S1
REPORT
sapbc401_exc_s1.
TYPE-POOLS icon.
INCLUDE bc401_exc_s1_agency.
INCLUDE bc401_exc_s1_carrier.
INCLUDE bc401_exc_s1_rental.
DATA:
go_hotel
go_vehicle
go_truck
go_bus
go_rental
go_passenger
go_cargo
go_carrier
go_agency
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
REF
REF
REF
REF
REF
TO
TO
TO
TO
TO
TO
TO
TO
TO
cl_hotel2,
lcl_vehicle,
lcl_truck,
lcl_bus,
lcl_rental,
lcl_passenger_plane,
lcl_cargo_plane,
lcl_carrier,
lcl_travel_agency.
DATA:
gv_text
TYPE string,
gx_inv_planetype TYPE REF TO cx_invalid_planetype.
START-OF-SELECTION.
*******************
******* create travel_agency
CREATE OBJECT go_agency
EXPORTING
iv_name = 'Travel&Smile Travel'.
© Copyright. All rights reserved.
399
Unit 9: Class-Based Exceptions
******* create hotel
CREATE OBJECT go_hotel
EXPORTING
iv_name = 'Sleep Well Hotel'
iv_beds = 345.
******* create rental
CREATE OBJECT go_rental
EXPORTING
iv_name = 'Happy Car Rental'.
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'MAN'
iv_cargo = 45.
******* create truck
CREATE OBJECT go_bus
EXPORTING
iv_make
= 'Mercedes'
iv_passengers = 80.
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'VOLVO'
iv_cargo = 48.
***** Create Carrier
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly'.
***** Passenger Plane
TRY.
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype = '747-500'
iv_seats
= 345.
CATCH cx_invalid_planetype INTO gx_inv_planetype.
gv_text = gx_inv_planetype->get_text( ).
WRITE:
/ icon_failure AS ICON,
gv_text.
ENDTRY.
*
*
*
*
*
*
*
*
*
*
400
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
WRITE:
/ icon_failure AS ICON,
© Copyright. All rights reserved.
Lesson: Defining and Raising Exceptions
*
*
'Wrong plane type'.
ENDIF.
***** cargo Plane
TRY.
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype = '747-200F'
iv_cargo
= 533.
CATCH cx_invalid_planetype INTO gx_inv_planetype.
gv_text = gx_inv_planetype->get_text( ).
WRITE:
/ icon_failure AS ICON,
gv_text.
ENDTRY.
*
*
*
*
*
*
*
*
*
*
*
*
*
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
******* show attributes of all partners of travel_agency
go_agency->display_attributes( ).
© Copyright. All rights reserved.
401
Unit 9: Class-Based Exceptions
LESSON SUMMARY
You should now be able to:
402
●
Define global exception classes
●
Raise class-based exceptions
●
Propagate exceptions
© Copyright. All rights reserved.
Unit 9
Lesson 3
Implementing Advanced Exception Handling
Techniques
LESSON OVERVIEW
This lesson explains the implementation of advanced exception handling techniques.
Business Example
You need to use advanced exception handling techniques to catch exceptions and to retry
after exception handling in your ABAP Objects programs. For this reason, you require the
following knowledge:
●
An understanding of predefined exception classes
●
An understanding of how to handle an exception class
●
An understanding of how to retry after an exception
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Explain the hierarchy of predefined exception classes
●
Explain different ways of handling an exception
●
Retry after exceptions
●
Implement resumable exceptions
●
Map exceptions
© Copyright. All rights reserved.
403
Unit 9: Class-Based Exceptions
The Hierarchy of Predefined Exception Classes
Figure 152: Integration of Standard Exceptions in the Runtime System
The figure shows how the standard exceptions in the runtime system are integrated into the
inheritance hierarchy of the exception classes.
The choice of the superclass influences the way that the syntax check and the runtime
environment handle a given exception. Some of the standard exception classes are as follows:
●
CX_STATIC_CHECK
If an exception class inherits from CX_STATIC_CHECK, you must either handle the
relevant exception or propagate it using the RAISING addition. If the exception is neither
handled nor propagated using the RAISING addition, the syntax check displays a warning.
When you define a new global exception class, CX_STATIC_CHECK is defined as the
superclass by default.
●
CX_DYNAMIC_CHECK
For subclasses of CX_DYNAMIC_CHECK, the syntax check displays no warning if
exceptions are neither handled nor propagated with the RAISING addition. If an exception
is raised at runtime and you neither handle nor propagate it, the system ends the program
with a runtime error.
404
© Copyright. All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
Note:
Typical examples of this situation are the predefined exceptions CX_SY_... for
errors that occur in the runtime environment. These are usually subclasses of
CX_DYNAMIC_CHECK.
●
CX_NO_CHECK
For subclasses of CX_NO_CHECK, you cannot propagate the corresponding exceptions
explicitly using the RAISING addition. If you do not handle these exceptions in the
processing block where they occur, they are automatically propagated. If the calling block
does not handle the exceptions, they are automatically propagated further on to the
highest call hierarchy level. If the exceptions are not handled on the top level, a runtime
error occurs at the point where they were raised. Some predefined exceptions with the
prefix CX_SY_... for error situations in the runtime environment are subclasses of
CX_NO_CHECK.
Exception Handling
After an exception was caught in a CATCH statement, you can handle it in many different
ways.
Techniques to Handle an Exception Caught in a CATCH Statement
1. Continue the program behind an ENDTRY statement after taking one of the following
actions:
●
Ignoring the exception (do nothing)
●
Issuing a warning
●
Writing to a protocol
●
Correcting the situation
2. Remove the cause of the error and start again from one of the following points:
●
From the beginning of the corresponding TRY block using statement RETRY.
RETRY is new as of SAP NetWeaver 7.0 EhP 2.
●
From where the exception occurred using statement RESUME.
RESUME is new as of SAP NetWeaver 7.0 EhP 2.
3. Raise and propagate one of the following exceptions:
●
The same exception object again using RAISE EXCEPTION <obj_ref>.
●
A new exception using RAISE EXCEPTION TYPE <exc_class>.
© Copyright. All rights reserved.
405
Unit 9: Class-Based Exceptions
The RETRY Statement
Figure 153: RETRY Statement
When you handle an exception in a CATCH block, use the RETRY statement to go back to the
TRY statement of the respective TRY-ENDTRY structure, for example, if the cause for the
exception was removed during the handling.
Hint:
This technique is new with Release SAP NetWeaver 7.0 EhP 2.
In the example, the main program catches the exception that the constructor raised and
propagated. After analyzing the exception object and correcting the error situation, the main
program repeats the whole TRY block using the RETRY statement.
Caution:
You must use RETRY with some caution. If you do not remove the cause of the
exception properly, your program will go into an infinite loop.
406
© Copyright. All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
Implementation of Resumable Exceptions
Figure 154: Resume Execution After a Resumable Exception
Use the RESUME statement to resume a program immediately after the statement that raised
the exception in the source code.
You must satisfy the following prerequisites to use the RESUME statement:
1. The exception must be caught with CATCH statement using the addition BEFORE
UNWIND. This ensures that the context of the exception is kept alive for a possible
RESUME. If the CATCH block exited without the RESUME statement, the system deletes
the context of the exception after the CATCH block is exited.
2. The exception must be raised with the RAISE RESUMABLE ... variant of the RAISE
EXCEPTION statement. This prepares the raising processing lock for the RESUME.
3. If the exception is propagated, you must mark it as resumable on all hierarchy levels by
using the RAISING RESUMABLE ( ... ) addition with the name of the exception class inside
the brackets. This prepares all methods that propagate the exception for a possible
RESUME.
Hint:
There is a checkbox for indicating the use of class base exceptions in the
interface of a function module and the signature of a method. When checked,
the function module or method must use all class-based exceptions. When
left unchecked. all classic exceptions must be used.
© Copyright. All rights reserved.
407
Unit 9: Class-Based Exceptions
The handler of a given exception checks whether, at runtime a given exception was raised and
propagated resumable or not. All exception objects provide public instance attribute
IS_RESUMABLE, which is set to ’X’ or ’ ’ by the framework, depending on how the exception
was raised and propagated. If you resume a non-resumable exception, you cause a runtime
error (exception class CX_SY_ILLEGAL_HANDLER).
Resume Execution After a Resumable Exception
In the example, shown in the figure, method GET_TECH_ATTR raises and propagates the
exception; the constructor propagates the exception further. All raising and propagating is
setup to be resumable. The main program handles the exception with CATCH BEFORE
UNWIND ..., checks that the exception indeed is resumable, and issues the RESUME
statement. The system resumes the execution of GET_TECH_ATTR immediately after the
RAISE RESUMABLE EXCEPTION statement is executed.
Hint:
In this example, you keep the context of the exception. Without the BEFORE
UNWIND addition, the system deletes the newly created instance before
executing the CATCH block. Resuming the GET_GET_TECH_ATTR method and
the constructor would not be possible.
Exception Mapping
Figure 155: Mapping Exceptions to Each Other
After catching an exception, the program can raise a second exception, and so on. An
exception object becomes invalid once the program leaves the CATCH block. Therefore, the
handler on the top level can only access the last exception object. However, you can chain
408
© Copyright. All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
exception objects, that is, you can let one exception object point to the one before, which
points to the one before it, and so on. The handler of an exception may follow the chain and
evaluates each exception object in the sequence.
All exception classes provide a public instance attribute PREVIOUS. You type the attribute
with REF TO CX_ROOT to point to arbitrary exception objects. The constructors of all
exception classes have an import parameter, PREVIOUS, of the same type, which can be used
to link an existing exception object to a new one.
In the example in the figure, the constructor catches the exception that has been raised by the
GET_TECH_ATTR method. After analyzing the exception, the constructor raises a new
exception of a different exception class. It chains the existing exception object to the new one
by passing a reference to the existing object to the constructor of the new object. As a result,
attribute PREVIOUS of the new exception object points to the exception object that preceded
it.
The main program catches the second exception and accesses to the second exception
object. However, by using public attribute PREVIOUS, the main program can navigate to the
other exception object and analyze it. The main program can access each instance in a chain
of exceptions and follow the history of the raised exceptions in the call hierarchy.
Implementation of Re-Raise Exceptions
Figure 156: Re-raising an Existing Exception Object
You raise class-based exceptions with one of the following variants of statement RAISE
EXCEPTION:
●
RAISE EXCEPTION TYPE <exception_class> [EXPORTING ...]
© Copyright. All rights reserved.
409
Unit 9: Class-Based Exceptions
This statement creates a new exception object, which is an instance of class
<exception_class>. Optionally, values can be provided for the constructor using the
EXPORTING addition.
●
RAISE EXCEPTION <object_ref>
This statement uses an existing exception object, namely whichever exception
object<object_ref> points to. This exception object is either created directly, using a
CREATE OBJECT statement or, more commonly, caught in a previous CATCH ... INTO ...
statement and pass explicitly to the caller.
In the example, the constructor catches exception CX_EXC, which is raised by the
GET_TECH_ATTR method. The constructor analyzes the exception object, performs
necessary adjustments, issues a warning, and so on. The constructor then decides to pass
the exception to the main program, where the exception is handled again.
410
© Copyright. All rights reserved.
Unit 9
Exercise 23
Map Exceptions to Each Other
Business Example
You want your program to use the class-based exception concept if an invalid plane type is
provided when creating an airplane instance. Instead of just propagating the exception raised
by GET_TECHNICAL_ATTRIBUTES, the constructor needs to handle it and raise a different
exception. You want the two exceptions to be chained together so that the main program can
evaluate both.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_EXC_S1
Solution: SAPBC401_EXC_S2
Handle an Exception Raised by a Method
In the constructor of local class LCL_AIRPLANE, handle the exception raised by method
GET_TECHNICAL_ATTRIBUTES.
1. Edit the implementation of the constructor of local class LCL_AIRPLANE.
Define a local object reference (suggested name: LX_INV_PLANETYPE) and choose its
type so that the reference may point to the exception object raised by method
GET_TECHNICAL_ATTRIBUTES.
2. Implement a TRY-ENDTRY structure for exception handling. Catch the exception object,
but leave the CATCH block empty for now.
Raise and Map a New Exception
Raise a new exception and map it to the original one. Adjust the constructor to propagate the
new exception to the main program.
1. In the constructor of LCL_AIRPLANE, raise a new exception of TYPE CX_INVALID_VALUE
during the handling of the exception raised by GET_TECHNICAL_ATTRIBUTES.
Hint:
Check the signature of exception class CX_INVALID_VALUE to see if you
need to provide values for any attributes it contains. Transfer the reference to
the original exception instance to the exception instance constructor.
© Copyright. All rights reserved.
411
Unit 9: Class-Based Exceptions
2. Make sure that the instance attribute PREVIOUS of the new exception object points to the
already existing exception object. Use import parameter PREVIOUS of the constructor
method.
3. Adjust the signature of the constructor so that it propagates the new exception.
4. Which other method signatures do you have to adjust to propagate the exception up to
the main program?
Handle the New Exception
In the main program, handle the new exception and evaluate the information of both the new
and the original exception instance.
1. Catch your new exception in the main program every time that you create an instance of
an airplane. Define a local reference variable for the purpose with a suitable reference type
(suggested name: GX_INV_VALUE).
2. Use this reference to extract the text of your new exception. Output the text on the list.
3. Use the same variables to extract the text of the original exception. Output the text on the
list.
412
© Copyright. All rights reserved.
Unit 9
Solution 23
Map Exceptions to Each Other
Business Example
You want your program to use the class-based exception concept if an invalid plane type is
provided when creating an airplane instance. Instead of just propagating the exception raised
by GET_TECHNICAL_ATTRIBUTES, the constructor needs to handle it and raise a different
exception. You want the two exceptions to be chained together so that the main program can
evaluate both.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_EXC_S1
Solution: SAPBC401_EXC_S2
Handle an Exception Raised by a Method
In the constructor of local class LCL_AIRPLANE, handle the exception raised by method
GET_TECHNICAL_ATTRIBUTES.
1. Edit the implementation of the constructor of local class LCL_AIRPLANE.
Define a local object reference (suggested name: LX_INV_PLANETYPE) and choose its
type so that the reference may point to the exception object raised by method
GET_TECHNICAL_ATTRIBUTES.
a) See the source code extract from the model solution.
2. Implement a TRY-ENDTRY structure for exception handling. Catch the exception object,
but leave the CATCH block empty for now.
a) See the source code extract from the model solution.
Raise and Map a New Exception
Raise a new exception and map it to the original one. Adjust the constructor to propagate the
new exception to the main program.
1. In the constructor of LCL_AIRPLANE, raise a new exception of TYPE CX_INVALID_VALUE
during the handling of the exception raised by GET_TECHNICAL_ATTRIBUTES.
© Copyright. All rights reserved.
413
Unit 9: Class-Based Exceptions
Hint:
Check the signature of exception class CX_INVALID_VALUE to see if you
need to provide values for any attributes it contains. Transfer the reference to
the original exception instance to the exception instance constructor.
a) See the source code extract from the model solution.
2. Make sure that the instance attribute PREVIOUS of the new exception object points to the
already existing exception object. Use import parameter PREVIOUS of the constructor
method.
a) See the source code extract from the model solution.
3. Adjust the signature of the constructor so that it propagates the new exception.
a) See the source code extract from the model solution.
4. Which other method signatures do you have to adjust to propagate the exception up to
the main program?
The constructors of LCL_CARGO_PLANE and LCL_PASSENGER_PLANE.
Handle the New Exception
In the main program, handle the new exception and evaluate the information of both the new
and the original exception instance.
1. Catch your new exception in the main program every time that you create an instance of
an airplane. Define a local reference variable for the purpose with a suitable reference type
(suggested name: GX_INV_VALUE).
a) See the source code extract from the model solution.
2. Use this reference to extract the text of your new exception. Output the text on the list.
a) See the source code extract from the model solution.
3. Use the same variables to extract the text of the original exception. Output the text on the
list.
a) See the source code extract from the model solution.
Include BC401_EXC_S2_CARRIER
*---------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*---------------------------------------------------*
CLASS lcl_airplane DEFINITION.
PUBLIC SECTION.
*
414
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
RAISING
cx_invalid_value,
cx_invalid_planetype,
© Copyright. All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
display_attributes.
CLASS-METHODS:
display_n_o_airplanes,
class_constructor.
EVENTS:
airplane_created.
PROTECTED SECTION.
CONSTANTS:
c_pos_1 TYPE i VALUE 30.
PRIVATE SECTION.
TYPES:
ty_planetypes TYPE STANDARD TABLE OF saplane
WITH NON-UNIQUE KEY planetype.
DATA:
mv_name
mv_planetype
mv_weight
mv_tankcap
TYPE
TYPE
TYPE
TYPE
string,
saplane-planetype,
saplane-weight,
saplane-tankcap.
CLASS-DATA:
gv_n_o_airplanes TYPE i,
gt_planetypes
TYPE ty_planetypes.
CLASS-METHODS:
get_technical_attributes
IMPORTING
iv_type
TYPE saplane-planetype
EXPORTING
ev_weight
TYPE saplane-weight
ev_tankcap TYPE saplane-tankcap
RAISING
cx_invalid_planetype.
ENDCLASS.
"lcl_airplane DEFINITION
*-----------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*
*-----------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
METHOD class_constructor.
SELECT * FROM saplane INTO TABLE gt_planetypes.
ENDMETHOD.
"class_constructor
METHOD constructor.
DATA:
lx_inv_planetype TYPE REF TO cx_invalid_planetype.
mv_name
= iv_name.
mv_planetype
= iv_planetype.
TRY.
get_technical_attributes(
EXPORTING
© Copyright. All rights reserved.
415
Unit 9: Class-Based Exceptions
iv_type = iv_planetype
IMPORTING
ev_weight = mv_weight
ev_tankcap = mv_tankcap ).
gv_n_o_airplanes = gv_n_o_airplanes + 1.
RAISE EVENT airplane_created.
CATCH cx_invalid_planetype INTO lx_inv_planetype.
RAISE EXCEPTION TYPE cx_invalid_value
EXPORTING
parnam
= 'IV_PLANETYPE'
previous = lx_inv_planetype.
ENDTRY.
ENDMETHOD.
"constructor
METHOD display_attributes.
WRITE:
/ icon_ws_plane AS ICON,
/ 'Name of Airplane'(001) ,
/ 'Type of Airplane:'(002),
/ 'Weight:'(003),
LEFT-JUSTIFIED,
/ 'Tank capacity:'(004),
LEFT-JUSTIFIED.
ENDMETHOD.
AT c_pos_1 mv_name,
AT c_pos_1 mv_planetype,
AT c_pos_1 mv_weight
AT c_pos_1 mv_tankcap
"display_attributes
METHOD display_n_o_airplanes.
SKIP.
WRITE:
/ 'Number of airplanes:'(ca1),
AT c_pos_1 gv_n_o_airplanes LEFT-JUSTIFIED.
ENDMETHOD.
"display_n_o_airplanes
METHOD get_technical_attributes.
DATA: ls_planetype TYPE saplane.
READ TABLE gt_planetypes INTO ls_planetype
WITH TABLE KEY planetype = iv_type
TRANSPORTING weight tankcap.
IF sy-subrc = 0.
ev_weight = ls_planetype-weight.
ev_tankcap = ls_planetype-tankcap.
ELSE.
*
RAISE wrong_planetype.
RAISE EXCEPTION TYPE cx_invalid_planetype
EXPORTING
planetype = iv_type.
ENDIF.
ENDMETHOD.
"get_technical_attributes
ENDCLASS.
"lcl_airplane IMPLEMENTATION
*------------------------------------------------*
*
CLASS lcl_cargo_plane DEFINITION
*------------------------------------------------*
*
416
© Copyright. All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
*----------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING FROM lcl_airplane.
PUBLIC SECTION.
*
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
iv_cargo
TYPE s_plan_car
RAISING
cx_invalid_value,
cx_invalid_planetype,
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:
mv_cargo TYPE s_plan_car.
ENDCLASS.
"lcl_cargo_plane DEFINITION
*-------------------------------------------------*
*
CLASS lcl_cargo_plane IMPLEMENTATION
*-------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
...
ENDCLASS.
"lcl_cargo_plane IMPLEMENTATION
*-------------------------------------------------*
*
CLASS lcl_passenger_plane DEFINITION
*-------------------------------------------------*
CLASS lcl_passenger_plane DEFINITION INHERITING FROM lcl_airplane.
PUBLIC SECTION.
*
METHODS:
constructor
IMPORTING
iv_name
TYPE string
iv_planetype TYPE saplane-planetype
iv_seats
TYPE s_seatsmax
RAISING
cx_invalid_value,
cx_invalid_planetype,
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:
mv_seats TYPE s_seatsmax.
ENDCLASS.
"lcl_passenger_plane DEFINITION
*------------------------------------------------*
*
CLASS lcl_passenger_plane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
© Copyright. All rights reserved.
417
Unit 9: Class-Based Exceptions
...
ENDCLASS.
"lcl_passenger_plane IMPLEMENTATION
*------------------------------------------------*
*
CLASS lcl_carrier DEFINITION
*------------------------------------------------*
CLASS lcl_carrier DEFINITION.
...
ENDCLASS.
"lcl_carrier DEFINITION
*------------------------------------------------*
*
CLASS lcl_carrier IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
...
ENDCLASS.
"lcl_carrier IMPLEMENTATION
Main Program SAPBC401_EXC_S2
REPORT
sapbc401_exc_s2.
TYPE-POOLS icon.
INCLUDE bc401_exc_s2_agency.
INCLUDE bc401_exc_s2_carrier.
INCLUDE bc401_exc_s2_rental.
DATA:
go_hotel
go_vehicle
go_truck
go_bus
go_rental
go_passenger
go_cargo
go_carrier
go_agency
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
REF
REF
REF
REF
REF
TO
TO
TO
TO
TO
TO
TO
TO
TO
cl_hotel2,
lcl_vehicle,
lcl_truck,
lcl_bus,
lcl_rental,
lcl_passenger_plane,
lcl_cargo_plane,
lcl_carrier,
lcl_travel_agency.
DATA:
gv_text
TYPE string,
gx_inv_value
TYPE REF TO cx_invalid_value.
* gx_inv_planetype TYPE REF TO cx_invalid_planetype.
START-OF-SELECTION.
*******************
******* create travel_agency
CREATE OBJECT go_agency
EXPORTING
iv_name = 'Travel&Smile Travel'.
******* create hotel
CREATE OBJECT go_hotel
EXPORTING
iv_name = 'Sleep Well Hotel'
iv_beds = 345.
418
© Copyright. All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
******* create rental
CREATE OBJECT go_rental
EXPORTING
iv_name = 'Happy Car Rental'.
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'MAN'
iv_cargo = 45.
******* create truck
CREATE OBJECT go_bus
EXPORTING
iv_make
= 'Mercedes'
iv_passengers = 80.
******* create truck
CREATE OBJECT go_truck
EXPORTING
iv_make = 'VOLVO'
iv_cargo = 48.
***** Create Carrier
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly'.
***** Passenger Plane
TRY.
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype = '747-500'
iv_seats
= 345.
CATCH cx_invalid_value INTO gx_inv_value.
gv_text = gx_inv_value->get_text( ).
WRITE:
/ icon_failure AS ICON,
gv_text.
gv_text = gx_inv_value->previous->get_text( ).
WRITE:
/ icon_failure AS ICON,
gv_text.
*
*
*
*
*
CATCH cx_invalid_planetype INTO gx_inv_planetype.
gv_text = gx_inv_planetype->get_text( ).
WRITE:
/ icon_failure AS ICON,
gv_text.
ENDTRY.
***** cargo Plane
TRY.
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype = '747-200F'
iv_cargo
= 533.
© Copyright. All rights reserved.
419
Unit 9: Class-Based Exceptions
CATCH cx_invalid_value INTO gx_inv_value.
gv_text = gx_inv_value->get_text( ).
WRITE:
/ icon_failure AS ICON,
gv_text.
gv_text = gx_inv_value->previous->get_text( ).
WRITE:
/ icon_failure AS ICON,
gv_text.
*
*
*
*
*
CATCH cx_invalid_planetype INTO gx_inv_planetype.
gv_text = gx_inv_planetype->get_text( ).
WRITE:
/ icon_failure AS ICON,
gv_text.
ENDTRY.
***** show attributes of all partners of travel_agency
go_agency->display_attributes( ).
420
© Copyright. All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
LESSON SUMMARY
You should now be able to:
●
Explain the hierarchy of predefined exception classes
●
Explain different ways of handling an exception
●
Retry after exceptions
●
Implement resumable exceptions
●
Map exceptions
© Copyright. All rights reserved.
421
Unit 9: Class-Based Exceptions
422
© Copyright. All rights reserved.
Unit 9
Learning Assessment
1. Which of the following statements is used to raise class-based exceptions?
Choose the correct answer.
X
A EXPORTING
X
B RAISE EXCEPTION
X
C CREATE OBJECT
X
D CATCH
2. Which of the following blocks is used to catch and handle exceptions?
Choose the correct answer.
X
A IMPORTING….RETURNING
X
B METHOD…. ENDMETHOD
X
C TRY … ENDTRY
X
D TRY...CATCH...ENDTRY
3. A class-based exception can only be handled if the statement that raised it is enclosed in a
TRY-ENDTRY control structure.
Determine whether this statement is true or false.
X
True
X
False
4. TRY-ENDTRY structures can be nested to any depth.
Determine whether this statement is true or false.
X
True
X
False
© Copyright. All rights reserved.
423
Unit 9: Learning Assessment
5. You can specify only two exception classes to the CATCH statement.
Determine whether this statement is true or false.
X
True
X
False
6. If an exception is raised, the name of the exception class is displayed in the __________
field in debugging mode.
Choose the correct answer.
X
A exception raised
X
B last exception object
X
C watchpoint
X
D layout
7. Which of the following syntax additions is used to propagate an exception from a
procedure?
Choose the correct answer.
X
A CATCH
X
B RAISING
X
C METHODS
X
D FORM
8. For subclasses of ____________ the corresponding exceptions cannot be propagated
explicitly using the RAISING addition.
Choose the correct answer.
424
X
A CX_STATIC_CHECK
X
B CX_NO_CHECK
X
C CX_DYNAMIC_CHECK
© Copyright. All rights reserved.
Unit 9: Learning Assessment
9. Which of the following are ways of handling an exception?
Choose the correct answers.
X
A Continue program
X
B Remove the cause of error
X
C Do not propagate an exception
X
D Call method CX_SYSTEM_HANDLE
10. Which of the following is used to jump back to the TRY statement?
Choose the correct answer.
X
A RETRY
X
B CATCH
X
C TRY-ENTRY
X
D RAISE
11. Which of the following is a prerequisite for using the RESUME statement?
Choose the correct answers.
X
A The exception has to be caught with addition BEFORE UNWIND.
X
B The exception has to be caught with addition AFTER UNWIND.
X
C The exception has to be propagated with addition RESUMABLE( ).
X
D The exception has to be raised with addition RESUMABLE.
© Copyright. All rights reserved.
425
Unit 9
Learning Assessment - Answers
1. Which of the following statements is used to raise class-based exceptions?
Choose the correct answer.
X
A EXPORTING
X
B RAISE EXCEPTION
X
C CREATE OBJECT
X
D CATCH
2. Which of the following blocks is used to catch and handle exceptions?
Choose the correct answer.
X
A IMPORTING….RETURNING
X
B METHOD…. ENDMETHOD
X
C TRY … ENDTRY
X
D TRY...CATCH...ENDTRY
3. A class-based exception can only be handled if the statement that raised it is enclosed in a
TRY-ENDTRY control structure.
Determine whether this statement is true or false.
X
True
X
False
4. TRY-ENDTRY structures can be nested to any depth.
Determine whether this statement is true or false.
426
X
True
X
False
© Copyright. All rights reserved.
Unit 9: Learning Assessment - Answers
5. You can specify only two exception classes to the CATCH statement.
Determine whether this statement is true or false.
X
True
X
False
6. If an exception is raised, the name of the exception class is displayed in the __________
field in debugging mode.
Choose the correct answer.
X
A exception raised
X
B last exception object
X
C watchpoint
X
D layout
7. Which of the following syntax additions is used to propagate an exception from a
procedure?
Choose the correct answer.
X
A CATCH
X
B RAISING
X
C METHODS
X
D FORM
8. For subclasses of ____________ the corresponding exceptions cannot be propagated
explicitly using the RAISING addition.
Choose the correct answer.
X
A CX_STATIC_CHECK
X
B CX_NO_CHECK
X
C CX_DYNAMIC_CHECK
© Copyright. All rights reserved.
427
Unit 9: Learning Assessment - Answers
9. Which of the following are ways of handling an exception?
Choose the correct answers.
X
A Continue program
X
B Remove the cause of error
X
C Do not propagate an exception
X
D Call method CX_SYSTEM_HANDLE
10. Which of the following is used to jump back to the TRY statement?
Choose the correct answer.
X
A RETRY
X
B CATCH
X
C TRY-ENTRY
X
D RAISE
11. Which of the following is a prerequisite for using the RESUME statement?
Choose the correct answers.
428
X
A The exception has to be caught with addition BEFORE UNWIND.
X
B The exception has to be caught with addition AFTER UNWIND.
X
C The exception has to be propagated with addition RESUMABLE( ).
X
D The exception has to be raised with addition RESUMABLE.
© Copyright. All rights reserved.
UNIT 10
Unit Testing
Lesson 1
Unit Testing with ABAP Unit
Exercise 24: Execute an ABAP Unit Test
430
437
UNIT OBJECTIVES
●
Perform unit testing
●
Use test classes and test methods
●
Perform advanced ABAP unit testing
© Copyright. All rights reserved.
429
Unit 10
Lesson 1
Unit Testing with ABAP Unit
LESSON OVERVIEW
This lesson explains how to use ABAP unit tests to verify the correct behavior of your
program.
Business Example
You want to use ABAP Unit tests for automated, efficient testing of your ABAP coding.
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Perform unit testing
●
Use test classes and test methods
●
Perform advanced ABAP unit testing
Unit Testing
Unit testing is a process in which a developer ensures that the smallest testable units of their
code, such as methods, are verifiable. This makes it easier to ensure quality, to refactor code,
to perform regression testing, and to implement according to the test-driven development
model. Unit testing is an integral part of the development phase.
Figure 157: Unit Test Principle
430
© Copyright. All rights reserved.
Lesson: Unit Testing with ABAP Unit
Unit tests are written as local classes within the main program of a global class (class pool).
They act as users of the class, and as such, they may only access its public components. Each
test is implemented as a method of the class, the aim being to perform remove operations on
the class under test that lead to a particular verifiable state of the class. Each test method is
executed independently.
Generation of Test Code
ABAP Unit is a unit-testing framework that is integrated into the ABAP language. ABAP Unit
tests are transported with the ABAP repository objects that they test, therefore, the source
code is available in all development, testing, and production systems.
Figure 158: Generation of Test Code
However, this does not necessarily mean that ABAP Unit tests can be executed in every
system. Profile parameter abap/test_generation specifies to which systems the load of the
tests are generated. Typically, test coding is generated only in development and test systems.
In production systems, test classes are excluded from the load versions to minimize the size
of the loads. This prevents the test coding from having any impact on the function and
performance in the production system.
Advantages of Unit Testing
●
Define your tests in ABAP
-
●
Easy testing while you develop
-
●
No need to learn a test script language
Test tool integrated in ABAP Workbench and ABAP Development Tools (ADT)
Mass Testing
© Copyright. All rights reserved.
431
Unit 10: Unit Testing
-
●
Easy execution and evaluation
-
●
Evaluate which percentage of your code is covered by your tests
No resource consumption in productive systems
-
●
Anybody can run a test without ABAP knowledge
Integrated Test Coverage
-
●
Unit test integrated in Code Inspector and ABAP Test Cockpit
Decide in which systems test coding is generated and loaded
Test classification with regard for time consumption and potential damage
-
Identify time consuming or critical tests (e.g. tests updating persistent data)
Definition of a Unit Test Class
ABAP Unit tests are realized as local test classes with the required test methods in your
application programs. You define local test classes by adding the FOR TESTING addition in
the class definition. Further additions are used to classify the tests according to their time
consumption and the impact on the data integrity. When you test your program using ABAP
Unit, an instance is generated automatically for each test class, and the corresponding test
methods are executed.
The definition of test classes provides a clear boundary between productive coding and test
coding. You can call productive coding from within the test classes. But the compiler will not
allow you to access a test class from an ordinary application class.
Figure 159: Definition of ABAP Unit Test Classes
Test Methods
Test methods are defined as instance methods without parameters (preferably private) in
your local test classes. Like a test class, their definition also requires the FOR TESTING
addition.
432
© Copyright. All rights reserved.
Lesson: Unit Testing with ABAP Unit
The Service Class CL_ABAP_UNIT_ASSERT
Figure 160: Implementation of ABAP Unit Test Methods
A test method contains program code to be executed for testing, followed by a check of the
results derived from the test code. The content of the variables to be tested is compared
against expected values by calling standard check methods of service class
CL_ABAP_UNIT_ASSERT (static methods ASSERT_...). If the respective values do not
correspond to the expectation, the check method can enter a note, a warning, or even an
error in the test log.
Method Parameters
Table 6: Method Import Parameters
Check methods have the following import parameters:
Parameter
Description
act
Variable to be checked
exp
Expected value (methods assert_equals, assert_differs)
msg
Message to be displayed in the log if the value does not match the expectation
lev
Gravity of error to be logged (class constants TOLERABLE, CRITICAL, FATAL)
quit
What is terminated if test fails (class constants NO, METHOD, CLASS,
PROGRAM)
© Copyright. All rights reserved.
433
Unit 10: Unit Testing
Check methods also have a return parameter
, assertion_failed (value = ’X’ /SPACE).
This can be used by the test method to find out the check results.
ABAP Unit Test Execution
To perform an ABAP Unit test, proceed as follows:
How to Perform an ABAP Unit Test
ABAP Workbench
●
For a Program, on the menu bar choose Program → Execute → Unit Tests.
●
For a Class, on the menu bar choose Class → Run → Unit Tests.
●
In the Object Name screen area, right-click the item name and choose Execute → Unit
Tests.
ABAP Development Tools (ADT)
●
On the Project Explorermenu bar, choose Run → Run As → ABAP Unit Tests.
Tools for Mass Testing
●
In the ABAP Test Cockpit (ATC), use check profile with checks BC_AUNIT,
BC_AUNIT_M, or BC_AUNIT_L.
●
In the Code Inspector (SCI), use check variant with check List of Checks → Dynamic
Tests → ABAP Unit.
ABAP Unit Testing is included in both ABAP development environments. In both
environments, you can perform ABAP Unit tests for single repository objects (class, function
group, program) and also for a complete development package. To allow for mass testing, the
Unit test framework is also included in other tools like the Code Inspector (transaction code:
SCI) and the ABAP Test Cockpit (transaction code ATC).
The figure, Example: Execute an ABAP Unit Test in the ABAP Workbench, illustrates how to
begin a Unit test for an executable program.
434
© Copyright. All rights reserved.
Lesson: Unit Testing with ABAP Unit
Figure 161: Example: Execute an ABAP Unit Test in the ABAP Workbench
ABAP Unit Test Results
Although the tests may be carried out differently, the results are presented in a similar way.
Figure 162: Example Test Result in the ABAP Workbench
On the left side of the figure, Example Test Result in the ABAP Workbench, there is a list of the
tests executed (test methods grouped by test classes). A red light indicates the classes and
methods with errors. When you choose an entry with a red light, a list of errors is displayed in
the Alerts and Messages screen area on the right side. When you click an error message, the
message details are displayed in the Analysis screen area. In the Analysis area you can
navigate to the source code of the test method.
© Copyright. All rights reserved.
435
Unit 10: Unit Testing
436
© Copyright. All rights reserved.
Unit 10
Exercise 24
Execute an ABAP Unit Test
Business Example
In your project some changes were made to the coding of the class LCL_CUSTOMER. Before
shipment you want to make sure that the basic functionality of this class is still intact. To do
this, execute the existing ABAP Unit tests.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_UNT_T1
Solution: SAPBC401_UNT_S1
Copy and Analyze a Program Containing an ABAP Unit Test Class
Copy, activate, and analyze the template program.
1. Copy the template program, SAPBC401_UNT_T1, and all of its components to
ZBC401_##_UNIT.
2. Save, check, and activate your program.
3. Analyze the program. How many local classes do you find?
4. How many test classes and test methods does it contain?
5. Execute the ABAP Unit tests for the program.
6. Analyze the result. How many errors do you find?
7. What problem situations do they refer to?
© Copyright. All rights reserved.
437
Unit 10: Unit Testing
Correct the Problems in the Code
1. Analyze the constructor of LCL_CUSTOMER. What is wrong with its implementation?
2. Correct the coding of the constructor implementation.
3. Save, check, and activate your program.
4. Repeat the Unit Test and verify that the errors have been removed.
438
© Copyright. All rights reserved.
Unit 10
Solution 24
Execute an ABAP Unit Test
Business Example
In your project some changes were made to the coding of the class LCL_CUSTOMER. Before
shipment you want to make sure that the basic functionality of this class is still intact. To do
this, execute the existing ABAP Unit tests.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Template: SAPBC401_UNT_T1
Solution: SAPBC401_UNT_S1
Copy and Analyze a Program Containing an ABAP Unit Test Class
Copy, activate, and analyze the template program.
1. Copy the template program, SAPBC401_UNT_T1, and all of its components to
ZBC401_##_UNIT.
a) In the Object Navigator, in the unnamed dropdown list on the left of the screen, choose
Program and enter the name of the template, SAPBC401_UNT_T1. Press Enter.
b) Under Object Name in the context menu of the program name and select Copy from
the context menu.
The Create Program SAPBC401_UNT_T1dialog box displays.
c) In the Create Program SAPBC401_UNT_T1dialog box, enter the name of the new
template, ZBC401_##_UNIT. Choose Copy.
The Copy Program SAPBC401_UNT_T1 to ZBC401_##_UNITdialog box displays.
d) On the Copy Program SAPBC401_UNT_T1 to ZBC401_##_UNITdialog box, select all
the component checkboxes. Choose Copy.
The Create Object Directory Entrydialog box displays.
e) In the Create Object Directory Entrydialog box, enter your package name and choose
Save.
The Prompt for transportable Workbench requestdialog box displays.
f) In the Prompt for transportable Workbench requestdialog box, enter the request name
supplied by your instructor. Choose Continue.
2. Save, check, and activate your program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
© Copyright. All rights reserved.
439
Unit 10: Unit Testing
3. Analyze the program. How many local classes do you find?
There are two local classes.
4. How many test classes and test methods does it contain?
There are two test methods in one test class.
5. Execute the ABAP Unit tests for the program.
a) In the Object Navigator, in the unnamed dropdown list on the left of the screen, choose
Program and enter the name of the program, then press Enter.
b) On the menu bar, choose Program → Execute → ABAP Unit Tests.
6. Analyze the result. How many errors do you find?
There are two errors in the program.
7. What problem situations do they refer to?
The constructor of the tested class raises an unexpected exception.
Correct the Problems in the Code
1. Analyze the constructor of LCL_CUSTOMER. What is wrong with its implementation?
After the SELECT statement, the check of SY-SUBRC is wrong. If SY-SUBRC does not
equal zero (0), the exception is raised.
2. Correct the coding of the constructor implementation.
a) See source code extract from the model solution.
3. Save, check, and activate your program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
4. Repeat the Unit Test and verify that the errors have been removed.
a) Repeat this step as before.
Solution: SAPBC401_UDT_S1
*&--------------------------------------------------------------------*
*& Report SAPBC401_UNT_S1
*&--------------------------------------------------------------------*
REPORT sapbc401_unt_s1.
*----------------------------------------------------------------------*
* Class lcl_customer (class under test)
440
© Copyright. All rights reserved.
Lesson: Unit Testing with ABAP Unit
*----------------------------------------------------------------------*
CLASS lcl_customer DEFINITION.
PUBLIC SECTION.
METHODS constructor
IMPORTING
iv_id TYPE s_customer
RAISING cx_bc401_no_data.
METHODS display_attributes.
PRIVATE SECTION.
DATA:
mv_id TYPE s_customer,
mv_name TYPE s_custname,
mv_city TYPE s_city,
mv_country TYPE country.
ENDCLASS.
CLASS lcl_customer IMPLEMENTATION.
METHOD constructor.
DATA ls_scustom TYPE scustom.
mv_id = iv_id.
SELECT SINGLE * FROM scustom
INTO ls_scustom
WHERE id = iv_id.
*
IF sy-subrc <> 0.
IF sy-subrc = 0.
mv_name = ls_scustom-name.
mv_city = ls_scustom-city.
mv_country = ls_scustom-country.
ELSE.
RAISE EXCEPTION TYPE cx_bc401_no_data.
ENDIF.
ENDMETHOD.
METHOD display_attributes.
WRITE:
/ 'Customer number'(cid), AT 40 mv_id,
/ 'Customer name'(nam), AT 40 mv_name,
/ 'City'(cit), AT 40 mv_city,
/ 'Country'(cny), AT 40 mv_country.
ENDMETHOD.
ENDCLASS.
*----------------------------------------------------------------------*
* class lcl_test_cust (test class)
*----------------------------------------------------------------------*
CLASS lcl_test_cust DEFINITION FOR TESTING
DURATION SHORT
© Copyright. All rights reserved.
441
Unit 10: Unit Testing
RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS check_constructor FOR TESTING.
METHODS check_constructor_exception FOR TESTING.
ENDCLASS.
CLASS lcl_test_cust IMPLEMENTATION.
METHOD check_constructor.
DATA lo_customer TYPE REF TO lcl_customer.
DATA lx_exception TYPE REF TO cx_bc401_no_data.
* Create instance
TRY.
CREATE OBJECT lo_customer
EXPORTING
iv_id = '00000001'.
CATCH cx_bc401_no_data INTO lx_exception. "
ENDTRY.
cl_aunit_assert=>assert_not_bound(
EXPORTING
act = lx_exception
msg = 'Constructor raises exception when it should
not'(rse)
level = cl_aunit_assert=>critical
quit = cl_aunit_assert=>method " Flusskontrolle im
Fehlerfall
).
ENDMETHOD.
METHOD check_constructor_exception.
DATA lo_customer TYPE REF TO lcl_customer.
DATA lx_exception TYPE REF TO cx_bc401_no_data.
* Create instance
TRY.
CREATE OBJECT lo_customer
EXPORTING
iv_id = '99999999'.
CATCH cx_bc401_no_data INTO lx_exception. "
ENDTRY.
cl_aunit_assert=>assert_bound(
EXPORTING
act = lx_exception
msg = 'Constructor does not raise exception when it
should'(rsn)
level = cl_aunit_assert=>tolerable
quit = cl_aunit_assert=>method
).
442
© Copyright. All rights reserved.
Lesson: Unit Testing with ABAP Unit
ENDMETHOD.
ENDCLASS.
DATA go_customer TYPE REF TO lcl_customer.
DATA gx_no_data TYPE REF TO cx_bc401_no_data.
DATA gv_text TYPE string.
PARAMETERS pa_cust TYPE sbook-customid.
START-OF-SELECTION.
TRY.
.
CREATE OBJECT go_customer
EXPORTING
iv_id = pa_cust.
CATCH cx_bc401_no_data INTO gx_no_data.
gv_text = gx_no_data->get_text( ).
WRITE / gv_text.
ENDTRY.
IF go_customer IS BOUND.
go_customer->display_attributes( ).
ENDIF.
© Copyright. All rights reserved.
443
Unit 10: Unit Testing
Test Fixtures
A fixture is a test configuration that is created before a test method is called, and ensures a
unique test behavior. A fixture consists of test data, test objects, resources, and connections.
Table 7: Private and Parameterless Methods in a Test Class
To create a fixture, implement the following private and parameterless methods in a test
class:
Methods
Description
SETUP
Instance method, which is executed before every single test
method of the class.
TEARDOWN
Instance method, which is executed after every single test
method of the class.
CLASS_SETUP
Static method, which is executed once before the first test
method of the class.
CLASS_TEARDOWN
Static method, which is executed once after the last test method of the class.
Table 8: Phase Model of Unit Test and Fixture Methods
1
Start internal session for test class
2
Class construction of test class
3
Setup of Class Fixture (method CLASS_SETUP)
4a
For each Test Method:
Create Test Class Instance
4b
Setup of Fixture (method SETUP)
4c
Execution of Test Method
4d
5
Teardown of Fixture (method TEARDOWN)
Teardown of Class Fixture (method CLASS_TEARDOWN)
The methods have predefined names, and are automatically called by the ABAP runtime
environment when the test is executed.
Hint:
Due to the way in which these methods are called, all tests that use the same
fixture must be included in the same test class.
The fixture methods always refer to the current class. In test classes that inherit from one
another, the fixture methods are executed for each class involved. The setup methods are
executed from the superclasses to the subclasses, and the teardown methods from the
subclasses to the superclasses.
444
© Copyright. All rights reserved.
Lesson: Unit Testing with ABAP Unit
Test Coverage
ABAP Unit allows you to verify the thoroughness of your unit testing and easily find any
untested code.
To run ABAP Unit tests with code coverage measurement, choose Execute → Unit Tests
With → Coverage from the development object’s context menu in the navigation area (ABAP
Workbench) or Coverage As → ABAP Unit Test from the context menu in the Project Explorer
(ADT).
The coverage that was achieved by running the ABAP Unit tests is displayed next to the test
result on an additional tab page.
Figure 163: Example Unit Test Coverage ADT
You can switch the display between statement coverage, branch coverage, and procedure
coverage (“procedure” standing for processing block).
Hint:
Coverage Analysis is much better integrated into ABAP Development Tools.
Whereas, in the ABAP workbench you only see a list of numbers.
Types of Coverage
ABAP Development Tools display the coverage in the source code editor as follows:
Statement Coverage
Every executable line is highlighted either green or red. Green indicates that the
statement was exceeded. Red indicates that the line was not executed.
Branch Coverage
Branches in your code are highlighted red if they were not executed. Branches are
highlighted green if they were run and resolved to both true and false. Branches are
highlighted yellow if they were run but resolved only to one condition, true or false.
Procedure Coverage
© Copyright. All rights reserved.
445
Unit 10: Unit Testing
Procedure entry points are highlighted green or red to indicate whether they were called
or not.
446
© Copyright. All rights reserved.
Lesson: Unit Testing with ABAP Unit
LESSON SUMMARY
You should now be able to:
●
Perform unit testing
●
Use test classes and test methods
●
Perform advanced ABAP unit testing
© Copyright. All rights reserved.
447
Unit 10: Unit Testing
448
© Copyright. All rights reserved.
Unit 10
Learning Assessment
1. In ABAP Unit, the SETUP method is called before each individual test method.
Determine whether this statement is true or false.
X
True
X
False
2. Which of the following statements about ABAP Unit tests are true?
Choose the correct answers.
X
A Test classes are not generated in a production system
X
B Test methods can access the private components of the class under test
X
C The class under test can access the methods of the test class
X
D Each test method is executed independently of all of the others
© Copyright. All rights reserved.
449
Unit 10
Learning Assessment - Answers
1. In ABAP Unit, the SETUP method is called before each individual test method.
Determine whether this statement is true or false.
X
True
X
False
2. Which of the following statements about ABAP Unit tests are true?
Choose the correct answers.
450
X
A Test classes are not generated in a production system
X
B Test methods can access the private components of the class under test
X
C The class under test can access the methods of the test class
X
D Each test method is executed independently of all of the others
© Copyright. All rights reserved.
UNIT 11
Object-Oriented Design
Patterns
Lesson 1
Implementing Advanced Object-Oriented Techniques
453
Lesson 2
Implementing the Singleton Pattern
Exercise 25: Implement the Singleton Pattern
463
467
Lesson 3
Implementing Factory Classes Using Friendship
Exercise 26: Implement a Factory Class Using Friendship
476
479
Lesson 4
Implementing Persistent Objects
490
UNIT OBJECTIVES
●
Implement abstract classes
●
Implement final classes
●
Access internal tables with object references
●
Call navigation methods
●
Create objects with the NEW operator
●
Work with conditions on dynamic type of an object reference
●
Restrict the visibility of the instance constructor
●
Implement factory methods
●
Implement the singleton pattern
●
Implement friendship relationships
●
Explain persistence services
●
Examine persistent classes
© Copyright. All rights reserved.
451
Unit 11: Object-Oriented Design Patterns
452
●
Create persistent objects
●
Read data with persistent objects
●
Create OO transactions
© Copyright. All rights reserved.
Unit 11
Lesson 1
Implementing Advanced Object-Oriented
Techniques
LESSON OVERVIEW
This lesson explains how to implement abstract classes and final classes, how to access
internal tables with object references, and how to call the navigation methods.
Business Example
You need to add special object-oriented programming techniques to your ABAP Objects
implementations. For this reason, you require the following knowledge:
●
An understanding of how to define abstract classes
●
An understanding of how to define abstract methods
●
An understanding of how to define final classes
●
An understanding of how to define final methods
●
An understanding of how to use public read-only attributes
●
An understanding of how to call navigational methods
●
An understanding of how to chain functional methods
●
An understanding of how to define the Visibility of the Instance Constructor
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement abstract classes
●
Implement final classes
●
Access internal tables with object references
●
Call navigation methods
●
Create objects with the NEW operator
●
Work with conditions on dynamic type of an object reference
●
Restrict the visibility of the instance constructor
© Copyright. All rights reserved.
453
Unit 11: Object-Oriented Design Patterns
Abstract Classes
Figure 164: Abstract Classes and Abstract Methods
Abstract class contains both definition and implementation but cannot be instantiated. Use
the ABSTRACT addition in the CLASS statement to create an abstract class. Super classes
are a typical use for abstract classes, as they are not to be instantiated themselves, but their
subclasses are.
In an abstract class, you can define abstract methods among other things. This means that
the abstract method cannot be implemented in that class. Instead, it is implemented in a
subclass of the class. If the subclass of that class is not abstract, the abstract methods must
be redefined and implemented in the subclass for the first time.
Note:
The relevant indicator is in the Class Builder on the Attributes tab page for that
class or method.
References to such abstract classes can be used for polymorphic access to subclass
instances. Static methods cannot be abstract because they cannot be redefined.
454
© Copyright. All rights reserved.
Lesson: Implementing Advanced Object-Oriented Techniques
Final Classes
Figure 165: Final Classes and Methods
Prevent a class from being inherited by using the FINAL addition with the class statement.
You can prevent a method from being redefined by using the FINAL addition with the methods
statement.
Note:
The relevant indicator is in the Class Builder on the Attributes tab page for that
class or method.
Thus, all methods of a final class are implicitly final. You may not repeat the FINAL addition in
the methods themselves. Classes that are abstract and final should only contain static
components.
Internal Tables with Object References
We have learned in a previous section that object references can be stored in internal tables.
This is used, in particular, to implement associations. However, we have not yet discussed
how we should retrieve a specific object from such a list. The figure Read Access to a Table
with Object References, gives an example of how this could be achieved.
© Copyright. All rights reserved.
455
Unit 11: Object-Oriented Design Patterns
Figure 166: Read Access to a Table with Object References
Object references can be stored in internal tables.
The example in the figure, Read Access to a Table with Object References, explains how to
retrieve a specific object from such a list. The object reference is stored in the table along with
some key information. In the example, the key information is the make and model of the
vehicle. The object reference can easily be retrieved through this key information. This
technique implies a redundant storage of information as the key values are already stored in
attributes of the object.
456
© Copyright. All rights reserved.
Lesson: Implementing Advanced Object-Oriented Techniques
Read Access Using Public Attributes
Figure 167: Read Access Using Public Attributes
As shown in the figure, Read Access Using Public Attributes, the key information redundancy
can be avoided by making the key attributes public. Public attributes can be used directly in
the statements to access internal tables like READ TABLE and LOOP AT. The expression
TABE_LINE used here is a built-in part of the ABAP language. When the line type of an internal
table is an elementary data type instead of a structure type, you need to use TABLE_LINE.
Such internal tables have just one unnamed column. TABLE_LINE is used as the generic
column name for this single column.
Hint:
It is against the fundamental principles of object-oriented programming to make
attributes public. Unfortunately, ABAP does not allow you to use functional
methods (like the methods in our example GET_MAKE, GET_MODEL, and so on)
on the left side of WHERE clauses and WITH KEY additions. Therefore, public
attributes are only used in some special cases in read-only mode.
© Copyright. All rights reserved.
457
Unit 11: Object-Oriented Design Patterns
Navigation Methods and Chain Method Calls
Figure 168: Navigation Methods and Chaining of Method Calls
Associations like aggregations and compositions are an important design principle of objectoriented programming. An association means that at runtime, an instance of one class stores
references to objects of another class.
Classes that have other classes associated with them often come with methods that return
one of the stored references to the caller. Such methods are often called navigation methods,
as they can be used to navigate from one object to another. In the example, the LCL_VEHICLE
class is associated with the LCL_RENTAL class. Class LCL_RENTAL provides the navigation
method GET_VEHICLE.
Often, the purpose of navigating from one object to another is to access a single method of
this other object. We can chain method calls, that is, we can directly call a method of the
object that the navigation method returns. This technique is not restricted to the chaining of
two methods. In more complicated object models, it is possible to chain any number of
methods.
458
© Copyright. All rights reserved.
Lesson: Implementing Advanced Object-Oriented Techniques
Creating Objects with the NEW Operator
Figure 169: Creating Objects with the NEW Operator
The NEW operator creates a new instance of a class, thus replacing CREATE OBJECT. After
NEW, you must specify the class that you want to instantiate. In the example in the figure,
Creating Objects with the NEW operator, the pound sign (#) denotes that the class to be
instantiated should be derived from the definition of the reference variable, so go_vehicle will
hold a reference to an instance of the class lcl_vehicle. In the second example a subclass
instance is created, therefore explicit typing with the desired subclass is necessary.
Note that the NEW operator can only accept the importing parameters of the constructor,
and that it is not possible to handle conventional sy-subrc-based exceptions. You handle
class-based exceptions by enclosing the statement containing the NEW operator in a TRY...
CATCH... ENDTRY block as normal.
The NEW operator is available since Release 7.40.
© Copyright. All rights reserved.
459
Unit 11: Object-Oriented Design Patterns
Figure 170: Using NEW at Expression Position
It is possible to use the NEW operator at many expression positions, especially as an actual
parameter of a method.
In the first example in the figure, Using NEW at Expression Position, an object is created just
before it is needed as input for an APPEND statement.
In the second example, immediately before a method call, we create a vehicle instance to use
it as actual value for a method parameter.
In the third example, we create the ALV instance using NEW, and, instead of passing a
reference variable to the i_parent parameter, we create an instance of the container control
on the fly. The inner NEW operator cannot use the pound sign to derive the type of the new
variable implicitly, since the formal parameter i_parent of the ALV constructor has the type
REF TO cl_gui_container, which is a superclass that may not be used as a container.
Conditions on Dynamic Type of Object Reference
Figure 171: Check Dynamic Type with Predicate Expression IS INSTANCE OF
From Release AS ABAP 7.50, you can use the expression IS INSTANCE OFto find out whether
an object reference points to an instance of a particular class. IS INSTANCE OF is true if the
object in question is an instance of either the specified class or one of its subclasses.
460
© Copyright. All rights reserved.
Lesson: Implementing Advanced Object-Oriented Techniques
Figure 172: Special Case Distinction CASE TYPE OF for Object Reference Variables
Available from Release 7.50, the control structure CASE TYPE OFallows you to distinguish
between different possible types of an object reference. The corresponding WHEN TYPE
block is processed if the dynamic type of the object reference variable corresponds to the
given class. The optional addition INTO allows you to perform a down cast directly by
specifying a reference variable.
Visibility of the Instance Constructor
Figure 173: Implicit Setting of the Instance Constructor’s Visibility
In ABAP Objects, we can restrict the visibility of the instance constructor. If the visibility of the
instance constructor is restricted, the CREATE OBJECT statements to instantiate this class is
only allowed in certain parts of the coding.
The types of visibilities for the instance constructor are as follows:
●
PRIVATE
© Copyright. All rights reserved.
461
Unit 11: Object-Oriented Design Patterns
If a class has a private instance constructor, it can only be instantiated from within the
class itself, typically in static methods defined for that purpose. These methods are
sometimes called Factory-Methods.
●
PROTECTED
If the instance constructor is protected, the visibility is extended to all of its subclasses,
that is, the subclasses can also create instances of the class.
●
PUBLIC
A public instance constructor is the default visibility setting: Instances of the class can be
created anywhere, inside the class itself, inside other classes, or, even in a non-objectoriented part of the program (for example, the main program).
Set the visibility by using the CREATE addition with the CLASS statement.
Note:
The relevant indicator is in the Class Builder on the Attributes tab page for the
relevant class.
Hint:
The visibility of the constructor is not set by placing the definition of the method
CONSTRUCTOR in the respective section of the class definition. In fact, before
SAP NetWeaver 7.0, it was mandatory to place the constructor syntactically in
the public section. Since SAP NetWeaver 7.0, it is allowed, but not required to
place the constructor in the protected or private section - if this is not more
restrictive than the CREATE… addition in the class definition. This is to increase
the readability of the coding.
LESSON SUMMARY
You should now be able to:
462
●
Implement abstract classes
●
Implement final classes
●
Access internal tables with object references
●
Call navigation methods
●
Create objects with the NEW operator
●
Work with conditions on dynamic type of an object reference
●
Restrict the visibility of the instance constructor
© Copyright. All rights reserved.
Unit 11
Lesson 2
Implementing the Singleton Pattern
LESSON OVERVIEW
This lesson explains the concepts of factory methods, the singleton pattern, and their
implementation.
Business Example:
You need to add special object-oriented programming techniques to your ABAP Objects
implementations. For this reason, you require the following knowledge:
●
An understanding of factory method
●
An understanding of singleton pattern
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement factory methods
●
Implement the singleton pattern
Factory Methods
Restricting the visibility of the instance constructor only makes sense if somewhere within the
class (or its subclasses, in case of CREATE PROTECTED) the instantiation is done.
Often, such classes provide a public static method that creates an instance of this class and
returns the reference to this instance to the caller. Such methods are sometimes called
factory methods. Factory methods are executed when an instance of the class is created and
has some advantages as compared to the instance constructor.
Advantages of factory methods
●
A factory method can have coding that executes before the actual instantiation.
For example, the method can perform checks, read data from the database, or set locks,
before actually creating the instance. If an error occurs, no instance is created; and, no
memory is allocated for it.
●
Classes can have more than one factory method. Each of the methods can have a different
implementation and signature as well.
The different factory method makes it possible to create instances of the same class
based on different information. For example, one factory method creates a new instance
that offers input parameters for all attributes, while another factory method only imports
key information and then retrieve the other attribute values from the database.
●
Use factory methods to administrate the instances of a class within the class itself.
© Copyright. All rights reserved.
463
Unit 11: Object-Oriented Design Patterns
The administration of the instance within the class is often used to avoid the creation of
many identical instances. A reference of every new instance is stored in a private static
attribute of the class (an internal table). Whenever the factory method is called, it first
checks whether an instance with this key already exists. If so, it returns the existing
instance instead of creating a new one.
●
Use a factory method to instantiate one of the subclasses rather than the class itself.
As an example, the factory method of an airplane class can check the plane type, then
instantiate either a cargo or a passenger plane.
Example for a Class with Factory Method
Figure 174: Example for a Class with Factory Method
The example illustrates a class with a Factory Method and using a static attribute to reference
all its instances. The instantiation is restricted to the class and is only done in static method
FACTORY. When the method is called, the factory method checks whether an identical
instance has already been created. If so, it returns the existing instance instead of creating a
new one.
Hint:
In this example, it is not necessary to make attributes public for the READ TABLE
statement. As the factory method lies within the class, it has full access to all
private attributes.
464
© Copyright. All rights reserved.
Lesson: Implementing the Singleton Pattern
The Singleton Pattern
Figure 175: Singleton Class - Using a Factory Method
Use the singleton concept to prevent a class from being instantiated more than once for the
same program context.
There are various different ways to implement a singleton class. The first singleton pattern is
a special case of the factory concept. Instead of storing several instances, the class stores
only one instance. When the factory method GET_INSTANCE is called for the first time, it
instantiates the class. For every subsequent call, it returns the reference to the existing
object.
© Copyright. All rights reserved.
465
Unit 11: Object-Oriented Design Patterns
Singleton Class - Using the Static Constructor
Figure 176: Singleton Class - Using the Static Constructor
The class uses its static constructor to create the single instance in advance. The
GET_INSTANCE method does not create the instance but only returns a reference to the
already existing instance.
Hint:
In a third variant of the singleton pattern, the GO_INSTANCE static attribute is
made public and read-only. The GET_INSTANCE method is not required.
466
© Copyright. All rights reserved.
Unit 11
Exercise 25
Implement the Singleton Pattern
Business Example
To improve the robustness of your application, you need to create two kinds of airplanes
(passenger and cargo), implement them as final classes so they are not further specialized.
Only specific airplanes are created and the travel agency can only be instantiated once.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_GCL_S2
Solution: SAPBC401_SPC_S1
Use the Techniques of ABAP Objects to Avoid Further Specialization
Use the techniques of ABAP Objects to avoid the further specialization of passenger and
cargo planes.
1. Declare classes LCL_PASSENGER_PLANE and LCL_CARGO_PLANE as FINAL class.
2. What happens if you declare class LCL_AIRPLANE as FINAL class ?
3. What would happen if you make method DISPLAY_ATTRIBUTES in class LCL_AIRPLANE a
final method?
Use the Techniques of ABAP Objects to Inhibit the Instantiation of a Class
Use the techniques of ABAP Objects to inhibit the instantiation of class LCL_AIRPLANE.
1. Declare LCL_AIRPLANE as an abstract class.
2. Prove that it is not allowed to instantiate the class itself. In your main program, declare a
reference variable TYPE REF TO lcl_airplane and implement a CREATE OBJECT statement
for it. After the syntax check, remove the CREATE OBJECT statement.
Implement a Singleton Pattern
Make sure that the LCL_TRAVEL_AGENCY class can only be instantiated once in your
program. Implement one of the singleton patterns discussed in the course.
© Copyright. All rights reserved.
467
Unit 11: Object-Oriented Design Patterns
1. Restrict the visibility of the instance constructor and inhibit any inheritance from the class.
2. Define a static attribute to store a reference to the one instance there. Depending on the
pattern you implement, make it private, or public and read-only.
3. Depending on the pattern you implement, define and implement a static constructor
and/or a GET_INSTANCE method. Implement the instantiation of the class according to
the singleton pattern.
4. Adjust the main program. Remove the CREATE OBJECT statement for the travel agency
from the main program. Depending on the single pattern you implemented, replace it with
a call of the GET_INSTANCE method or with an access to the public attribute.
5. Optional: If you have implemented a pattern that includes a GET_INSTANCE method, use
a method chain to retrieve the singleton instance and call its DISPLAY_ATTRIBUTE
method in one statement.
468
© Copyright. All rights reserved.
Unit 11
Solution 25
Implement the Singleton Pattern
Business Example
To improve the robustness of your application, you need to create two kinds of airplanes
(passenger and cargo), implement them as final classes so they are not further specialized.
Only specific airplanes are created and the travel agency can only be instantiated once.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_GCL_S2
Solution: SAPBC401_SPC_S1
Use the Techniques of ABAP Objects to Avoid Further Specialization
Use the techniques of ABAP Objects to avoid the further specialization of passenger and
cargo planes.
1. Declare classes LCL_PASSENGER_PLANE and LCL_CARGO_PLANE as FINAL class.
a) See the source code extract from the model solution.
2. What happens if you declare class LCL_AIRPLANE as FINAL class ?
This
results
in
a
syntax
error
as
classes
LCL_PASSENGER_PLANE already inherited from this class.
LCL_CARGO_PLANE
and
3. What would happen if you make method DISPLAY_ATTRIBUTES in class LCL_AIRPLANE a
final method?
This results in a syntax error as the method is already redefined in classes
LCL_CARGO_PLANE and LCL_PASSENGER_PLANE.
Use the Techniques of ABAP Objects to Inhibit the Instantiation of a Class
Use the techniques of ABAP Objects to inhibit the instantiation of class LCL_AIRPLANE.
1. Declare LCL_AIRPLANE as an abstract class.
a) See the source code extract from the model solution.
2. Prove that it is not allowed to instantiate the class itself. In your main program, declare a
reference variable TYPE REF TO lcl_airplane and implement a CREATE OBJECT statement
for it. After the syntax check, remove the CREATE OBJECT statement.
a) Carry out this step as usual.
© Copyright. All rights reserved.
469
Unit 11: Object-Oriented Design Patterns
Implement a Singleton Pattern
Make sure that the LCL_TRAVEL_AGENCY class can only be instantiated once in your
program. Implement one of the singleton patterns discussed in the course.
1. Restrict the visibility of the instance constructor and inhibit any inheritance from the class.
a) Use the FINAL and CREATE PRIVATE additions to the CLASS ... DEFINITION
statement. Optionally, move the definition of the instance constructor to the private
section. See the source code extract from the model solution.
2. Define a static attribute to store a reference to the one instance there. Depending on the
pattern you implement, make it private, or public and read-only.
a) See the source code extract from the model solution.
3. Depending on the pattern you implement, define and implement a static constructor
and/or a GET_INSTANCE method. Implement the instantiation of the class according to
the singleton pattern.
a) See the source code extract from the model solution.
4. Adjust the main program. Remove the CREATE OBJECT statement for the travel agency
from the main program. Depending on the single pattern you implemented, replace it with
a call of the GET_INSTANCE method or with an access to the public attribute.
a) See the source code extract from the model solution.
5. Optional: If you have implemented a pattern that includes a GET_INSTANCE method, use
a method chain to retrieve the singleton instance and call its DISPLAY_ATTRIBUTE
method in one statement.
a) See the source code extract from the model solution.
Solution: Include BC401_SPC_S1_CARRIER
*------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*------------------------------------------------*
CLASS lcl_airplane DEFINITION ABSTRACT.
...
ENDCLASS.
"lcl_airplane DEFINITION
*------------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
...
ENDCLASS.
"lcl_airplane IMPLEMENTATION
*------------------------------------------------*
*
CLASS lcl_cargo_plane DEFINITION
*------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING
FROM lcl_airplane FINAL.
...
ENDCLASS.
"lcl_cargo_plane DEFINITION
*------------------------------------------------*
*
CLASS lcl_cargo_plane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
...
ENDCLASS.
"lcl_cargo_plane IMPLEMENTATION
470
© Copyright. All rights reserved.
Lesson: Implementing the Singleton Pattern
*------------------------------------------------*
*
CLASS lcl_passenger_plane DEFINITION
*------------------------------------------------*
CLASS lcl_passenger_plane DEFINITION INHERITING
FROM lcl_airplane FINAL.
...
ENDCLASS.
"lcl_passenger_plane DEFINITION
*------------------------------------------------*
*
CLASS lcl_passenger_plane IMPLEMENTATION
*------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
...
ENDCLASS.
"lcl_passenger_plane IMPLEMENTATION
Include BC401_SPC_S1_AGENCY
*-------------------------------------------------*
*
CLASS lcl_travel_agency DEFINITION
*-------------------------------------------------*
CLASS lcl_travel_agency DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
get_instance
RETURNING
value(ro_instance) TYPE REF TO lcl_travel_agency.
METHODS:
display_agency_partners,
display_attributes.
PRIVATE SECTION.
DATA:
mv_name
TYPE string,
mt_partners TYPE TABLE OF REF TO if_partner.
CLASS-DATA:
go_instance TYPE REF TO lcl_travel_agency.
METHODS:
constructor
IMPORTING
iv_name TYPE string.
METHODS:
on_partner_created FOR EVENT partner_created
OF if_partner
IMPORTING sender.
ENDCLASS.
"lcl_travel_agency DEFINITION
*---------------------------------------------------*
*
CLASS lcl_travel_agency IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_travel_agency IMPLEMENTATION.
METHOD get_instance.
IF go_instance IS NOT BOUND.
CREATE OBJECT go_instance
EXPORTING
iv_name = 'Travel&Smile Travel'.
© Copyright. All rights reserved.
471
Unit 11: Object-Oriented Design Patterns
ENDIF.
ro_instance = go_instance.
ENDMETHOD. "get_instance
METHOD display_attributes.
WRITE: / icon_private_files AS ICON,
'Travel Agency:'(007), mv_name.
SKIP.
display_agency_partners( ).
ENDMETHOD.
"display_attributes
METHOD display_agency_partners.
DATA:
lo_partner TYPE REF TO if_partner.
WRITE 'Here are the partners of the travel agency:'(008).
ULINE.
LOOP AT mt_partners INTO lo_partner.
lo_partner->display_partner( ).
ENDLOOP.
ENDMETHOD.
"display_agency_partners
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_partner_created FOR ALL INSTANCES.
ENDMETHOD.
"constructor
METHOD on_partner_created.
APPEND sender TO mt_partners.
ENDMETHOD.
"on_partner_created
ENDCLASS.
Main Program SAPBC401_SPC_S1
REPORT
sapbc401_spc_s1.
TYPE-POOLS icon.
INCLUDE bc401_spc_s1_agency.
INCLUDE bc401_spc_s1_carrier.
INCLUDE bc401_spc_s1_rental.
DATA:
go_hotel
go_agency
go_vehicle
go_truck
go_bus
go_rental
go_passenger
go_cargo
go_carrier
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
TYPE
REF
REF
REF
REF
REF
REF
REF
REF
REF
TO
TO
TO
TO
TO
TO
TO
TO
TO
cl_hotel2,
lcl_travel_agency,
lcl_vehicle,
lcl_truck,
lcl_bus,
lcl_rental,
lcl_passenger_plane,
lcl_cargo_plane,
lcl_carrier.
START-OF-SELECTION.
*******************
******* create travel_agency ***********************
* CREATE OBJECT go_agency
*
EXPORTING
*
iv_name = 'Travel&Smile Travel'.
472
© Copyright. All rights reserved.
Lesson: Implementing the Singleton Pattern
go_agency = lcl_travel_agency=>get_instance( ).
******* create hotel *******************************
CREATE OBJECT go_hotel
EXPORTING
iv_name = 'Sleep Well Hotel'
iv_beds = 345.
******* create rental *******************************
CREATE OBJECT go_rental
EXPORTING
iv_name = 'Happy Car Rental'.
******* create truck *********************************
CREATE OBJECT go_truck
EXPORTING
iv_make = 'MAN'
iv_cargo = 45.
******* create truck *********************************
CREATE OBJECT go_bus
EXPORTING
iv_make
= 'Mercedes'
iv_passengers = 80.
******* create truck *********************************
CREATE OBJECT go_truck
EXPORTING
iv_make = 'VOLVO'
iv_cargo = 48.
***** Create Carrier *********************************
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly Travel'.
***** Passenger Plane ********************************
CREATE OBJECT go_passenger
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
iv_seats
= 345
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
***** cargo Plane ************************************
CREATE OBJECT go_cargo
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
WRITE:
© Copyright. All rights reserved.
473
Unit 11: Object-Oriented Design Patterns
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
***** show attributes of all partners of travel_agency
go_agency->display_attributes( ).
* Optional part: Use method chain:
*
* lcl_travel_agency=>get_instance( )->display_attributes( ).
474
© Copyright. All rights reserved.
Lesson: Implementing the Singleton Pattern
LESSON SUMMARY
You should now be able to:
●
Implement factory methods
●
Implement the singleton pattern
© Copyright. All rights reserved.
475
Unit 11
Lesson 3
Implementing Factory Classes Using
Friendship
LESSON OVERVIEW
This lesson explains the method of implementing factory classes using friendship.
Business Example
As a developer create a factory class for airplanes using friendship. For this reason, you
require the following knowledge:
●
An understanding of the definition of friendship relationships
●
An understanding of friendship and inheritance
●
An understanding of the implementation of factory classes
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
Implement friendship relationships
Definition of Friendship Relationships
Figure 177: Definition of a Friendship Relationship Between Classes
476
© Copyright. All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
In some cases, classes have to work together so closely that one class needs access to the
other classes protected and private components. Similarly, one class might need to be able to
create instances of the other class regardless of the visibility of the constructor. To avoid
making these options available to all users of the class, use the concept of class friendship. A
class can grant friendship to other classes and interfaces and, hence, to all classes that
implement the interface.
To create friendship, use the FRIENDS addition of the CLASS statement or the FRIENDS tab
page in the Class Builder. All classes and interfaces to which friendship is granted are listed
there.
Granting friendship is unilateral.
A class granting friendship is not automatically a friend of the classes’ friends. If a class
granting friendship wants to access the non-public components of a friend, this friend must
also explicitly grant friendship to it.
Implementation of Factory Classes
Figure 178: Example of a Factory Class
A typical application of the friends concept is the definition of a factory class. Like the factory
method, a factory class creates and administrates the instances of a class. By outsourcing
the administration to a dedicated class, the class itself is kept smaller and easier to
understand.
In the example, LCL_FACTORY serves as a factory class for airplanes. LCL_FACTORY class
provides a public method CREATE_AIRPLANE in which CREATE_AIRPLANE either
instantiates class LCL_AIRPLANE or returns a reference to an already existing instance. To
restrict the instantiation, class LCL_AIRPLANE is defined with addition CREATE PRIVATE. By
adding FRIENDS LCL_FACTORY, the friendship allows the factory class and only the factory
class to create airplane instances and to access the private attributes.
© Copyright. All rights reserved.
477
Unit 11: Object-Oriented Design Patterns
Hint:
Another advantage of the dedicated factory class is that if the class has
subclasses, the decision on which of the classes should be instantiated could be
done inside the factory class rather than by the calling program. In the example,
the CREATE_AIRPLANE method could create and return an instance of either
LCL_CARGO_PLANE or LCL_PASSENGER_PLANE depending on the plane type.
Friendship and Inheritance
The friend attribute is inherited. Classes that inherit from friends and interfaces containing a
friend as a component interface, also become friends. Therefore, we advise that extreme
caution must be taken when granting friendship. The higher up a friend is in the inheritance
tree, the more subclasses can access all components of a class that grants friendship.
Conversely, granting friendship is not inherited. A friend of a superclass is, therefore, not
automatically a friend of its subclasses.
478
© Copyright. All rights reserved.
Unit 11
Exercise 26
Implement a Factory Class Using Friendship
Business Example
Instead of instantiating airplane objects in the main program directly, create airplanes by
using a factory class. The factory class should provide one single factory method. Depending
on the input, the factory class decides inside this factory method, whether to create a cargo
plane or a passenger plane.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_SPC_S1
Solution: SAPBC401_ SPC_S2
Define a Factory Class
In your program, define a factory class (suggested name: LCL_AIRPLANE_FACTORY) with a
public static factory method for airplanes (suggested name: CREATE_AIRPLANE).
The factory method should have suitably typed import parameters for name, plane type,
cargo, and seats. The factory method for import parameters cargo and seats can be optional.
It should also have a single returning parameter to return a reference to an airplane instance,
either a cargo plane or a passenger plane.
1. Edit the include, which contains the classes for airplanes. Add the definition of the new
class there.
2. Within the class, define a public static factory method for airplanes. Define four import
parameters for name, plane type, cargo, and seats. Name and type them exactly as in the
constructors of your airplane classes. Make the parameters for cargo and seats optional.
Hint:
Use addition OPTIONAL.
3. Define a returning parameter (suggested name: RO_AIRPLANE).
© Copyright. All rights reserved.
479
Unit 11: Object-Oriented Design Patterns
How do you have to type the parameter so that the method can return a reference to
either a cargo plane instance or a passenger plane instance?
Implement a Factory Method
Implement the factory method. Depending on the optional parameter that is supplied, create
either a cargo plane instance or a passenger plane instance. Define a suitable exception and
raise it if both optional parameters are supplied or none of them.
1. In the factory method, define two local reference variables. Type one with the class for
cargo planes (LCL_CARGO_PLANE) and one with the class for passenger planes
(LCL_PASSENGER_PLANE).
2. Implement an IF-structure in which you analyze the content of the import parameters for
cargo and seats. Create either an instance of the cargo plane class or the passenger plane
class. In the case of success, move the reference to the new object to the returning
parameter.
3. In the definition of the factory class, add two exceptions. One that you raise if a wrong
plane type was specified (suggested name: WRONG_PLANETYPE), and one that you raise
if both or none of the optional parameters were supplied (suggested name:
WRONG_PARAM_COMBINATION).
Restrict Object Creation to Factory Classes
Restrict the creation of cargo planes and passenger planes so that they can only be created
from inside the factory class.
1. Use the CREATE PRIVATE addition to restrict the instantiation of the classes for cargo
planes and passenger planes. Optionally, move the constructor definitions of both classes
to the private section.
2. Use the FRIENDS addition to allow the instantiation of the classes for cargo planes and
passenger planes from inside the factory class.
Hint:
You have to use statement CLASS... DEFINITION DEFERRED before the
definition of the airplane classes. Otherwise, the factory class or at least its
name, is not known to the syntax check when it reaches the FRIENDS
addition.
Replace Direct Instantiations by Calls of the Factory Method
Adjust your main program. Remove the direct instantiations of airplanes and replace them by
calls of the factory method.
1. Replace the instantiations of airplanes with calls of the factory method.
Hint:
If you have used exactly the same parameter names as in the constructors,
you can keep the parameter passing.
480
© Copyright. All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
2. Do you have to actually receive the references to the new objects?
3. Save, check activate, test, and debug your program.
© Copyright. All rights reserved.
481
Unit 11
Solution 26
Implement a Factory Class Using Friendship
Business Example
Instead of instantiating airplane objects in the main program directly, create airplanes by
using a factory class. The factory class should provide one single factory method. Depending
on the input, the factory class decides inside this factory method, whether to create a cargo
plane or a passenger plane.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_SPC_S1
Solution: SAPBC401_ SPC_S2
Define a Factory Class
In your program, define a factory class (suggested name: LCL_AIRPLANE_FACTORY) with a
public static factory method for airplanes (suggested name: CREATE_AIRPLANE).
The factory method should have suitably typed import parameters for name, plane type,
cargo, and seats. The factory method for import parameters cargo and seats can be optional.
It should also have a single returning parameter to return a reference to an airplane instance,
either a cargo plane or a passenger plane.
1. Edit the include, which contains the classes for airplanes. Add the definition of the new
class there.
a) Refer the source text excerpt from the model solution.
2. Within the class, define a public static factory method for airplanes. Define four import
parameters for name, plane type, cargo, and seats. Name and type them exactly as in the
constructors of your airplane classes. Make the parameters for cargo and seats optional.
Hint:
Use addition OPTIONAL.
a) Refer the source text excerpt from the model solution.
3. Define a returning parameter (suggested name: RO_AIRPLANE).
482
© Copyright. All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
How do you have to type the parameter so that the method can return a reference to
either a cargo plane instance or a passenger plane instance?
You have to type the parameter with the common superclass of cargo planes and
passenger planes, that is, TYPE REF TO lcl_airplane.
a) Refer the source text excerpt from the model solution.
Implement a Factory Method
Implement the factory method. Depending on the optional parameter that is supplied, create
either a cargo plane instance or a passenger plane instance. Define a suitable exception and
raise it if both optional parameters are supplied or none of them.
1. In the factory method, define two local reference variables. Type one with the class for
cargo planes (LCL_CARGO_PLANE) and one with the class for passenger planes
(LCL_PASSENGER_PLANE).
a) Refer the source text excerpt from the model solution.
2. Implement an IF-structure in which you analyze the content of the import parameters for
cargo and seats. Create either an instance of the cargo plane class or the passenger plane
class. In the case of success, move the reference to the new object to the returning
parameter.
a) Refer the source text excerpt from the model solution.
3. In the definition of the factory class, add two exceptions. One that you raise if a wrong
plane type was specified (suggested name: WRONG_PLANETYPE), and one that you raise
if both or none of the optional parameters were supplied (suggested name:
WRONG_PARAM_COMBINATION).
a) Refer the source text excerpt from the model solution.
Restrict Object Creation to Factory Classes
Restrict the creation of cargo planes and passenger planes so that they can only be created
from inside the factory class.
1. Use the CREATE PRIVATE addition to restrict the instantiation of the classes for cargo
planes and passenger planes. Optionally, move the constructor definitions of both classes
to the private section.
a) Refer the source text excerpt from the model solution.
2. Use the FRIENDS addition to allow the instantiation of the classes for cargo planes and
passenger planes from inside the factory class.
Hint:
You have to use statement CLASS... DEFINITION DEFERRED before the
definition of the airplane classes. Otherwise, the factory class or at least its
name, is not known to the syntax check when it reaches the FRIENDS
addition.
a) Refer the source text excerpt from the model solution.
Replace Direct Instantiations by Calls of the Factory Method
Adjust your main program. Remove the direct instantiations of airplanes and replace them by
calls of the factory method.
© Copyright. All rights reserved.
483
Unit 11: Object-Oriented Design Patterns
1. Replace the instantiations of airplanes with calls of the factory method.
Hint:
If you have used exactly the same parameter names as in the constructors,
you can keep the parameter passing.
a) Refer the source text excerpt from the model solution.
2. Do you have to actually receive the references to the new objects?
No. Through the message handling implemented earlier, the carrier instance takes care of
all new airplane instances and aggregates them.
3. Save, check activate, test, and debug your program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
d) To test your program, on the application toolbar, choose the Direct Processingbutton.
e) To debug the program, on the application toolbar, choose Execute, or press F8.
Include BC401_SPC_S2_CARRIER
CLASS lcl_airplane_factory DEFINITION DEFERRED.
*----------------------------------------------------*
*
CLASS lcl_airplane DEFINITION
*
*----------------------------------------------------*
CLASS lcl_airplane DEFINITION ABSTRACT.
...
ENDCLASS.
"lcl_airplane DEFINITION
*-----------------------------------------------------*
*
CLASS lcl_airplane IMPLEMENTATION
*
*-----------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
...
ENDCLASS.
"lcl_airplane IMPLEMENTATION
*-----------------------------------------------------*
*
CLASS lcl_cargo_plane DEFINITION
*-----------------------------------------------------*
*
*-----------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION
INHERITING FROM lcl_airplane FINAL
CREATE PRIVATE
FRIENDS lcl_airplane_factory.
...
484
© Copyright. All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
ENDCLASS.
"lcl_cargo_plane DEFINITION
*-----------------------------------------------------*
*
CLASS lcl_cargo_plane IMPLEMENTATION
*-----------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
...
ENDCLASS.
"lcl_cargo_plane IMPLEMENTATION
*-----------------------------------------------------*
*
CLASS lcl_passenger_plane DEFINITION
*-----------------------------------------------------*
CLASS lcl_passenger_plane DEFINITION INHERITING
FROM lcl_airplane
FINAL
CREATE PRIVATE
FRIENDS lcl_airplane_factory.
...
ENDCLASS.
"lcl_passenger_plane DEFINITION
*---------------------------------------------------*
*
CLASS lcl_passenger_plane IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
...
ENDCLASS.
"lcl_passenger_plane IMPLEMENTATION
*--------------------------------------------------*
*
CLASS lcl_carrier DEFINITION
*--------------------------------------------------*
CLASS lcl_carrier DEFINITION.
...
ENDCLASS.
"lcl_carrier DEFINITION
*--------------------------------------------------*
*
CLASS lcl_carrier IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
...
ENDCLASS.
"lcl_carrier IMPLEMENTATION
*--------------------------------------------------*
*
CLASS lcl_airplane_factory DEFINITION
*--------------------------------------------------*
CLASS lcl_airplane_factory DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
create_airplane
IMPORTING
iv_name
iv_planetype
iv_cargo
iv_seats
RETURNING
© Copyright. All rights reserved.
TYPE
TYPE
TYPE
TYPE
string
saplane-planetype
s_plan_car OPTIONAL
s_seatsmax OPTIONAL
485
Unit 11: Object-Oriented Design Patterns
value(ro_airplane) TYPE REF TO lcl_airplane
EXCEPTIONS
wrong_planetype
wrong_param_combination.
ENDCLASS.
"lcl_airplane_factory DEFINITION
*--------------------------------------------------*
*
CLASS lcl_airplane_factory IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_airplane_factory IMPLEMENTATION.
METHOD create_airplane.
DATA:
lo_cargo
TYPE REF TO lcl_cargo_plane,
lo_passenger TYPE REF TO lcl_passenger_plane.
IF iv_cargo IS NOT INITIAL AND iv_seats IS INITIAL.
CREATE OBJECT lo_cargo
EXPORTING
iv_name
= iv_name
iv_planetype
= iv_planetype
iv_cargo
= iv_cargo
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
RAISE wrong_planetype.
ELSE.
ro_airplane = lo_cargo.
ENDIF.
ELSEIF iv_cargo IS INITIAL AND iv_seats IS NOT INITIAL.
CREATE OBJECT lo_passenger
EXPORTING
iv_name
= iv_name
iv_planetype
= iv_planetype
iv_seats
= iv_seats
EXCEPTIONS
wrong_planetype = 1.
IF sy-subrc <> 0.
RAISE wrong_planetype.
ELSE.
ro_airplane = lo_passenger.
ENDIF.
ELSE.
RAISE wrong_param_combination.
ENDIF.
ENDMETHOD.
ENDCLASS.
"create_airplane
"lcl_airplane_factory IMPLEMENTATION
SAPBC401_SPC_S2
REPORT
sapbc401_spc_s2.
TYPE-POOLS icon.
INCLUDE bc401_spc_s2_agency.
INCLUDE bc401_spc_s2_carrier.
486
© Copyright. All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
INCLUDE bc401_spc_s2_rental.
DATA:
go_agency
TYPE REF TO lcl_travel_agency,
go_hotel
TYPE REF TO cl_hotel2,
go_vehicle
TYPE REF TO lcl_vehicle,
go_truck
TYPE REF TO lcl_truck,
go_bus
TYPE REF TO lcl_bus,
go_rental
TYPE REF TO lcl_rental,
*go_passenger TYPE REF TO lcl_passenger_plane,
*go_cargo
TYPE REF TO lcl_cargo_plane,
go_carrier
TYPE REF TO lcl_carrier.
START-OF-SELECTION.
*******************
******* create travel_agency ***********************
* CREATE OBJECT go_agency
*
EXPORTING
*
iv_name = 'Travel&Smile Travel'.
go_agency = lcl_travel_agency=>get_instance( ).
******* create hotel *******************************
CREATE OBJECT go_hotel
EXPORTING
iv_name = 'Sleep Well Hotel'
iv_beds = 345.
******* create rental ******************************
CREATE OBJECT go_rental
EXPORTING
iv_name = 'Happy Car Rental'.
******* create truck *******************************
CREATE OBJECT go_truck
EXPORTING
iv_make = 'MAN'
iv_cargo = 45.
******* create truck *******************************
CREATE OBJECT go_bus
EXPORTING
iv_make
= 'Mercedes'
iv_passengers = 80.
******* create truck *******************************
CREATE OBJECT go_truck
EXPORTING
iv_make = 'VOLVO'
iv_cargo = 48.
***** Create Carrier *******************************
CREATE OBJECT go_carrier
EXPORTING
iv_name = 'Smile&Fly-Travel'.
***** Passenger Plane ******************************
lcl_airplane_factory=>create_airplane(
EXPORTING
iv_name
= 'LH BERLIN'
iv_planetype
= '747-400'
© Copyright. All rights reserved.
487
Unit 11: Object-Oriented Design Patterns
iv_seats
= 345
EXCEPTIONS
wrong_planetype
= 1
wrong_param_combination = 2 ).
IF sy-subrc = 1.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
***** cargo Plane **********************************
lcl_airplane_factory=>create_airplane(
EXPORTING
iv_name
= 'US Hercules'
iv_planetype
= '747-200F'
iv_cargo
= 533
EXCEPTIONS
wrong_planetype
= 1
wrong_param_combination = 2 ).
IF sy-subrc = 1.
WRITE:
/ icon_failure AS ICON,
'Wrong plane type'.
ENDIF.
***** show attributes of all partners of travel_agency
go_agency->display_attributes( ).
488
© Copyright. All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
LESSON SUMMARY
You should now be able to:
●
Implement friendship relationships
© Copyright. All rights reserved.
489
Unit 11
Lesson 4
Implementing Persistent Objects
LESSON OVERVIEW
This lesson shows you how to implement persistent objects.
Business Example
You need to use Persistent Objects to access your database tables and also Object-Oriented
(OO) transactions in your ABAP Objects programs. For this reason, you require the following
knowledge:
●
An understanding of persistence services
●
An understanding of persistent classes
●
An understanding of how to create persistent objects
●
An understanding of how to read data with persistent objects
●
An understanding of how to create OO transactions
LESSON OBJECTIVES
After completing this lesson, you will be able to:
490
●
Explain persistence services
●
Examine persistent classes
●
Create persistent objects
●
Read data with persistent objects
●
Create OO transactions
© Copyright. All rights reserved.
Lesson: Implementing Persistent Objects
Persistence Services
Figure 179: Simulation of an Object-Oriented Database Management System
In principle, ABAP programs work with data and objects that are only valid at runtime. The
data and objects used in ABAP programs are transient. The data in memory is temporary and
disappears when the program ends. To store the data permanently and independent of the
program, you must store it in a database. Theoretically, you can also use files at the operating
system level.
For this purpose, the persistence services for ABAP Objects were introduced in SAP
NetWeaver Application Server (SAP NetWeaver AS). On request, the ABAP developer can use
these services and write the current attribute values of objects as persistent to the associated
transparent tables. To read the values from the tables, persistent services can be used to
import the values into an object previously defined as persistent. When doing this, the
persistence services use the ABAP Open SQL interface.
You will use the persistence services with object-oriented programming techniques. In this
way, you can simulate an object-oriented database management system using a relational
database management system and ABAP Objects.
Persistent Classes
To use the persistence service for objects, you must create their types as persistent classes
in Class Builder. The term persistent class indicates that the persistence service manages the
instances of the class and their state. (Global classes are generally persistent. The question is
whether or not their instances are also persistent.)
To ensure that the instances of persistent classes are unique, they must contain key
attributes. You can type these either as worldwide unique identification numbers (object
GUID) or semantic keys.
When you create a persistent class ZCL_<name>, Class Builder automatically generates
methods for getting and setting its attributes. In addition, the system also generates other
© Copyright. All rights reserved.
491
Unit 11: Object-Oriented Design Patterns
repository objects, including the class actor (also known as the class agent) ZCA_<name>.
Programs must call the methods of this class to manage the instances of persistent classes,
that is, persistent objects. The class actor also performs the actual database access. It
automatically inherits the required methods from the basis class ZCB_<name>. You can
redefine these methods, if necessary. For example, extend database accesses. The class
actor is a singleton instance and has a friendship relationship with the persistent class.
Creation of Persistent Objects
Figure 180: Generating and Writing to Persistent Objects
In the program, you need to define a reference variable with the type of the class actor and fill
it with the reference from the static attribute AGENT. You can then create a new instance of
the persistent class using its method CREATE_PERSISTENT. The ABAP developer creates its
interface from the definition of the key attributes of the persistent class. If a persistent object
of the same persistence class with the same key attributes already exists in the program, the
class-based exception CX_OS_OBJECT_EXISTING is triggered. By default, the data is saved
by an asynchronous update. You must start this process by using the COMMIT WORK
statement. Thus, the instances of the persistent class do not become persistent objects until
after that point.
492
© Copyright. All rights reserved.
Lesson: Implementing Persistent Objects
Access to Persistent Objects
Figure 181: Reading Persistent Objects
You can load a single persistent object back into a program using the GET_PERSISTENT
method. When doing so, you must pass the key values to the interface parameters so that you
can uniquely restore the object. If the program does not find the object, it raises the classbased exception CX_OS_OBJECT_NOT_FOUND.
You can retrieve a larger set of persistent objects by using the Query Service. It is possible to
provide a selection, much like the WHERE-clause of a SELECT statement, as well as the
ordering criteria.
To Create Persistent Classes
1. Model the class for your persistent objects.
2. Find or create a suitable transparent table that has a field for each attribute of the class. If
necessary, adapt the attributes of the class to match the technical field attributes of the
transparent table.
Note:
There must be a primary key field in the table for each key attribute of the
class or there must be a key attribute of the class for each primary key field in
the table.
3. In the Class Builder, create a persistent class as described in the SAP Library. Define the
persistence mapping to the table.
© Copyright. All rights reserved.
493
Unit 11: Object-Oriented Design Patterns
OO Transaction
Figure 182: Creating an OO Transaction Code
In transaction maintenance, you can create transaction code as an OO transaction. This
means that you link the transaction code either to the transaction service of the ABAP
Objects Services for persistent objects or a public method in a global or local class of a
program. When calling this type of OO transaction, which is linked to an instance method, the
system automatically creates an instance of the class in its own internal session and then
executes this instance method.
Caution:
You still require procedural framework programs for screen fields.
If the OO Transaction Modelflag is set, the system links the transaction code to the
transaction service of the ABAP Objects Services. Conversely, if it is not set, you can call any
method in a global or local class.
Users, therefore, now have the opportunity to call methods themselves in the usual way
(using menu options, command field entries, and so on).
494
© Copyright. All rights reserved.
Lesson: Implementing Persistent Objects
Caution:
Global classes in ABAP Objects cannot contain screen definitions.
Therefore, when you create a link to a global class, note the following points:
●
The constructor cannot contain any IMPORTING parameters.
●
You cannot process ABAP list displays.
Breaking these rules will not cause a syntax error or message from the Extended Syntax
Check. Instead, you will either cause a runtime error or there will be no display
Therefore, you may have to resort to using methods in local program classes. Naturally, you
can then use all the conventional dialog programming techniques.
To Create OO Transactions
You can create an OO transaction by using the following steps:
1. In the Create Transactiondialog box, enter a description in the Short Text field.
2. Choose the Method of a Class (OO Transaction)option as an Initial Object.
3. If you want to link the transaction code to a normal instance method, leave the OO
Transaction Model checkbox unselected.
4. Enter the Class Name and Method. If you are using a local class, select the Local in
Program checkbox and enter the program name.
5. Save the transaction code.
LESSON SUMMARY
You should now be able to:
●
Explain persistence services
●
Examine persistent classes
●
Create persistent objects
●
Read data with persistent objects
●
Create OO transactions
© Copyright. All rights reserved.
495
Unit 11: Object-Oriented Design Patterns
496
© Copyright. All rights reserved.
Unit 11
Learning Assessment
1. Static _____________ cannot be abstract because they cannot be redefined.
Choose the correct answer.
X
A classes
X
B structures
X
C methods
X
D attributes
2. You can prevent a class from being inherited from by defining it as final.
Determine whether this statement is true or false.
X
True
X
False
3. An association means that at runtime an instance of one class stores references to
objects of another class.
Determine whether this statement is true or false.
X
True
X
False
4. If the visibility of the instance constructor is changed from private to protected, the
visibility is extended to all of its subclasses.
Determine whether this statement is true or false.
X
True
X
False
© Copyright. All rights reserved.
497
Unit 11: Learning Assessment
5. Which of the following are the advantages of a factory method?
Choose the correct answers.
X
A A factory method can have coding that is executed before the actual instantiation.
X
B A class can have more than one factory method with different implementations
and signatures.
X
C Factory methods cannot be used to administrate the instances of a class within the
class itself.
X
D A factory method cannot be used to instantiate one of the subclasses rather than
the class itself.
6. Which of the following concepts is used to provide a class access to the private
components of the other class?
Choose the correct answer.
X
A Singleton
X
B Friendship
X
C Interface
X
D Casting
7. What should you do to use the persistence service for objects?
Choose the correct answer.
X
A You must type it as an object GUID.
X
B You must type it as a semantic key.
X
C You must create their types as persistent classes in the Class Builder.
8. Which class-based exception is triggered if a persistent object of the same persistent
class with the same key attributes already exists in the program?
Choose the correct answer.
498
X
A CX_SY_ZERODIVIDE
X
B CX_SY_MOVE_CAST_ERROR
X
C CX_OS_OBJECT_EXISTING
X
D CX_ROOT
© Copyright. All rights reserved.
Unit 11: Learning Assessment
9. How can you create a new instance of a persistent class?
Choose the correct answer.
X
A By using the CREATE_PERSISTENT method of the class agent
X
B By using the AGENT attribute
X
C By using the CX_OS_OBJECT_EXISTING class-based exception
X
D By using the COMMIT WORK statement
10. How can you load a single persistent object back into a program?
Choose the correct answer.
X
A By using the CREATE_PERSISTENT method
X
B By using the CX_OS_OBJECT_EXISTING class-based exception
X
C By using the Query Service
X
D By using the GET_PERSISTENT method
11. How can you retrieve a larger set of persistent objects?
Choose the correct answer.
X
A By using the Query Service
X
B By using the CREATE_PERSISTENT method
X
C By using the CX_OS_OBJECT_EXISTING class-based exception
X
D By using the GET_PERSISTENT method
© Copyright. All rights reserved.
499
Unit 11
Learning Assessment - Answers
1. Static _____________ cannot be abstract because they cannot be redefined.
Choose the correct answer.
X
A classes
X
B structures
X
C methods
X
D attributes
2. You can prevent a class from being inherited from by defining it as final.
Determine whether this statement is true or false.
X
True
X
False
3. An association means that at runtime an instance of one class stores references to
objects of another class.
Determine whether this statement is true or false.
X
True
X
False
4. If the visibility of the instance constructor is changed from private to protected, the
visibility is extended to all of its subclasses.
Determine whether this statement is true or false.
500
X
True
X
False
© Copyright. All rights reserved.
Unit 11: Learning Assessment - Answers
5. Which of the following are the advantages of a factory method?
Choose the correct answers.
X
A A factory method can have coding that is executed before the actual instantiation.
X
B A class can have more than one factory method with different implementations
and signatures.
X
C Factory methods cannot be used to administrate the instances of a class within the
class itself.
X
D A factory method cannot be used to instantiate one of the subclasses rather than
the class itself.
6. Which of the following concepts is used to provide a class access to the private
components of the other class?
Choose the correct answer.
X
A Singleton
X
B Friendship
X
C Interface
X
D Casting
7. What should you do to use the persistence service for objects?
Choose the correct answer.
X
A You must type it as an object GUID.
X
B You must type it as a semantic key.
X
C You must create their types as persistent classes in the Class Builder.
8. Which class-based exception is triggered if a persistent object of the same persistent
class with the same key attributes already exists in the program?
Choose the correct answer.
X
A CX_SY_ZERODIVIDE
X
B CX_SY_MOVE_CAST_ERROR
X
C CX_OS_OBJECT_EXISTING
X
D CX_ROOT
© Copyright. All rights reserved.
501
Unit 11: Learning Assessment - Answers
9. How can you create a new instance of a persistent class?
Choose the correct answer.
X
A By using the CREATE_PERSISTENT method of the class agent
X
B By using the AGENT attribute
X
C By using the CX_OS_OBJECT_EXISTING class-based exception
X
D By using the COMMIT WORK statement
10. How can you load a single persistent object back into a program?
Choose the correct answer.
X
A By using the CREATE_PERSISTENT method
X
B By using the CX_OS_OBJECT_EXISTING class-based exception
X
C By using the Query Service
X
D By using the GET_PERSISTENT method
11. How can you retrieve a larger set of persistent objects?
Choose the correct answer.
502
X
A By using the Query Service
X
B By using the CREATE_PERSISTENT method
X
C By using the CX_OS_OBJECT_EXISTING class-based exception
X
D By using the GET_PERSISTENT method
© Copyright. All rights reserved.
UNIT 12
Runtime Type Services
Lesson 1
Using Runtime Type Identification (RTTI)
Exercise 27: Describe Object Type Properties at Runtime
504
511
UNIT OBJECTIVES
●
Explain RTTI
●
Describe structure type properties at runtime
●
Describe object type properties at runtime
© Copyright. All rights reserved.
503
Unit 12
Lesson 1
Using Runtime Type Identification (RTTI)
LESSON OVERVIEW
This lesson describes how to implement run time type identification.
Business Example
You want to find out of which class a given object is an instance. You also want to find the
properties of any given class, interface, or data type. For this reason you require the following
knowledge:
●
An understanding of run time type identification
●
An understanding of how to query structure type properties at runtime
LESSON OBJECTIVES
After completing this lesson, you will be able to:
504
●
Explain RTTI
●
Describe structure type properties at runtime
●
Describe object type properties at runtime
© Copyright. All rights reserved.
Lesson: Using Runtime Type Identification (RTTI)
RTTI
Figure 183: Dynamic Type Analysis with RTTI Classes
Since the introduction of ABAP Objects, a class-based concept has been developed, called
Run Time Type Identification (RTTI). RTTI determines type attributes at runtime. RTTI
includes all ABAP types and covers all the functions of the now obsolete statements
DESCRIBE FIELD and DESCRIBE TABLE. RTTI includes a description class for each type with
special attributes for special type attributes.
The class hierarchy of the description classes corresponds to the hierarchy of types in ABAP
Objects. In addition, the description classes for complex types, references, classes, and
interfaces have special methods that you can use to specify references to subtypes. You can
use these methods to navigate through a compound type to all its subtypes.
© Copyright. All rights reserved.
505
Unit 12: Runtime Type Services
RTTI – Methods and Attributes of the Root Class
Figure 184: RTTI – Methods and Attributes of the Root Class
To obtain a reference to a description object of a type, use the static methods of the class
CL_ABAP_TYPEDESCR or the navigation methods of the special description class. The
description objects are then created from one of the subclasses. At runtime, exactly one
description object exists for each type. The attributes of the description object contain
information on the attributes of the type.
506
© Copyright. All rights reserved.
Lesson: Using Runtime Type Identification (RTTI)
Structured Type RTTI Descriptions
Figure 185: RTTI – Querying Structure Attributes
The example in the figure RTTI – Querying Structure Attributes, shows how to identify the
attributes of a structure using the subclass CL_ABAP_STRUCTDESCR from RTTI.
To identify the attributes of a structure, we first define a reference to the appropriate
description class. The description class has a COMPONENTS attribute that you can use to
describe the components of the relevant structure. Because the COMPONENTS attribute is
an internal table, you also need to define a work area with a compatible line type.
The functional method call provides the reference to the description instance of the structure
that you want to query.
The abstract class CL_ABAP_TYPEDESCR contains the static method DESCRIBE_BY_DATA.
Its returning parameter is typed as a reference to this superclass. However, since the actual
parameter is a reference to the subclass CL_ABAP_STRUCTDESCR, you need to assign the
object using a down-cast.
You can then access the attributes of the description instance in any form. In this example,
the program displays the component names as column headers. (For clarity, we have omitted
the formatting options.)
© Copyright. All rights reserved.
507
Unit 12: Runtime Type Services
Object Type RTTI Descriptions
Figure 186: RTTI – Querying Object-Type Attributes
In our previous business example with the travel agency and its business partner, we specified
that an instance of the vehicle rental class (LCL_RENTAL) reacts to an event by including the
vehicle instance that triggered the event in a list. The triggering instances include both buses
(LCL_BUS) and trucks (LCL_TRUCK).
To extend the example, assume that the vehicle rental company is only interested in buses.
The SENDER parameter of the event handler method contains the reference to the triggering
vehicle instance. Its dynamic object type must be analyzed to determine whether the vehicle
in question is a bus or a truck.
A functional RTTI method call returns the reference to the description instance of the
transferred vehicle instance.
The abstract class CL_ABAP_TYPEDESCR has DESCRIBE_BY_OBJECT_ REF method. You
type DESCRIBE_BY_OBJECT_REF returning parameter as a reference to
CL_ABAP_TYPEDESCR . However, since you type the actual parameter GO_DESCR on the
subclass CL_ABAP_CLASSDESCR, you need to assign the object using a down-cast.
Now, you can access the attributes of the description instance in any way. The functional
method GET_RELATIVE_NAME supplies the class name.
508
© Copyright. All rights reserved.
Lesson: Using Runtime Type Identification (RTTI)
Note:
It is possible to query object type attributes at run time without using RTTI
classes. For example, you can use a down-cast assignment from SENDER to a
reference variable that has a LCL_BUS static type. This results in a runtime error
for vehicle instances that are not buses. You can then catch this runtime error. In
this case, the fact that a runtime error was not triggered is the criterion for
including a vehicle into the vehicle list.
© Copyright. All rights reserved.
509
Unit 12: Runtime Type Services
510
© Copyright. All rights reserved.
Unit 12
Exercise 27
Describe Object Type Properties at Runtime
Business Example
The airline (LCL_CARRIER) wants to determine the highest cargo value of its cargo airplanes.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_RTT_T1
Solution: SAPBC401_RTT_S1
Determine the highest cargo value for all cargo airplanes that you have entered in your
application. The cargo airplanes are present in the class LCL_CARRIER (of the airline).
1. In an earlier exercise, you created method GET_MAX_CARGO to calculate the highest
cargo value. RTTI can solve this more easily. Therefore, use RTTI instead of the TRYENDTRY procedure. You no longer need to catch the runtime error for a downcast,
because you can determine the type of reference variable using an appropriate RTTI call.
2. Save, check, activate, and test the program.
3. Since SAP NetWeaver Application Server (SAP NetWeaver AS) 7.50, there is another
option for a safe downcast, the IS INSTANCE OF condition. Comment out your solution
based on a RTTI method call and instead use this condition to solve the problem.
4. Save, check, activate, and test the program again.
© Copyright. All rights reserved.
511
Unit 12
Solution 27
Describe Object Type Properties at Runtime
Business Example
The airline (LCL_CARRIER) wants to determine the highest cargo value of its cargo airplanes.
Note:
This exercise uses the main program file ZBC401_##_MAIN completed in the
previous exercise. If not complete, copy the model solution from the previous
exercise. In the exercises for this course, when the input values include ##,
replace ## with your group number.
Template: SAPBC401_RTT_T1
Solution: SAPBC401_RTT_S1
Determine the highest cargo value for all cargo airplanes that you have entered in your
application. The cargo airplanes are present in the class LCL_CARRIER (of the airline).
1. In an earlier exercise, you created method GET_MAX_CARGO to calculate the highest
cargo value. RTTI can solve this more easily. Therefore, use RTTI instead of the TRYENDTRY procedure. You no longer need to catch the runtime error for a downcast,
because you can determine the type of reference variable using an appropriate RTTI call.
a) Refer to the source code extract provided in the model solution.
2. Save, check, activate, and test the program.
a) Save your program.
b) To check your program, on the application toolbar, choose the Check button.
c) To activate your program, on the application toolbar, choose the Activate button.
3. Since SAP NetWeaver Application Server (SAP NetWeaver AS) 7.50, there is another
option for a safe downcast, the IS INSTANCE OF condition. Comment out your solution
based on a RTTI method call and instead use this condition to solve the problem.
a) Refer to the source code extract provided in the model solution (it is commented out
as this exercise deals mainly with RTTI.)
4. Save, check, activate, and test the program again.
a) Carry out this step in the usual manner.
Solution: Include Program BC401_RTT_S1_CARRIER
*--------------------------------------------------*
* CLASS lcl_airplane DEFINITION
*--------------------------------------------------*
512
© Copyright. All rights reserved.
Lesson: Using Runtime Type Identification (RTTI)
CLASS lcl_airplane DEFINITION.
...
ENDCLASS. "lcl_airplane DEFINITION
*--------------------------------------------------*
* CLASS lcl_airplane IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_airplane IMPLEMENTATION.
...
ENDCLASS. "lcl_airplane IMPLEMENTATION
*--------------------------------------------------*
* CLASS lcl_cargo_plane DEFINITION
*--------------------------------------------------*
CLASS lcl_cargo_plane DEFINITION INHERITING
FROM lcl_airplane.
ENDCLASS. "lcl_cargo_plane DEFINITION
*--------------------------------------------------*
* CLASS lcl_cargo_plane IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_cargo_plane IMPLEMENTATION.
...
ENDCLASS. "lcl_cargo_plane IMPLEMENTATION
*--------------------------------------------------*
* CLASS lcl_passenger_plane DEFINITION
*--------------------------------------------------*
CLASS lcl_passenger_plane DEFINITION INHERITING
FROM lcl_airplane.
...
ENDCLASS. "lcl_passenger_plane DEFINITION
*--------------------------------------------------*
* CLASS lcl_passenger_plane IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_passenger_plane IMPLEMENTATION.
...
ENDCLASS. "lcl_passenger_plane IMPLEMENTATION
*--------------------------------------------------*
* CLASS lcl_carrier DEFINITION
*--------------------------------------------------*
CLASS lcl_carrier DEFINITION.
PUBLIC SECTION.
INTERFACES if_partner.
METHODS:
constructor IMPORTING iv_name TYPE string,
on_airplane_created FOR EVENT airplane_created
OF lcl_airplane
IMPORTING sender,
display_attributes.
PRIVATE SECTION.
DATA:
mv_name TYPE string,
mt_airplanes TYPE TABLE OF REF TO lcl_airplane.
METHODS:
display_airplanes,
get_max_cargo RETURNING value(rv_max_cargo) TYPE s_plan_car.
© Copyright. All rights reserved.
513
Unit 12: Runtime Type Services
ENDCLASS. "lcl_carrier DEFINITION
*--------------------------------------------------*
* CLASS lcl_carrier IMPLEMENTATION
*--------------------------------------------------*
CLASS lcl_carrier IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
SET HANDLER on_airplane_created FOR ALL INSTANCES.
RAISE EVENT if_partner~partner_created.
ENDMETHOD. "constructor
METHOD if_partner~display_partner.
display_attributes( ).
ENDMETHOD. "if_partners~display_partner
METHOD on_airplane_created.
APPEND sender TO mt_airplanes.
ENDMETHOD. "on_airplane_created
METHOD display_attributes.
DATA:
lv_max_cargo TYPE s_plan_car.
SKIP 2.
WRITE: icon_flight AS ICON,
mv_name.
ULINE.
ULINE.
me->display_airplanes( ).
lv_max_cargo = me->get_max_cargo( ).
WRITE: / 'Capacity of biggest cargo plane:'(max),
lv_max_cargo LEFT-JUSTIFIED.
ENDMETHOD. "display_attributes
METHOD display_airplanes.
DATA: lo_plane TYPE REF TO lcl_airplane.
LOOP AT mt_airplanes INTO lo_plane.
lo_plane->display_attributes( ).
ENDLOOP.
ENDMETHOD. "display_airplanes
METHOD get_max_cargo.
DATA:
lo_plane TYPE REF TO lcl_airplane,
lo_cargo TYPE REF TO lcl_cargo_plane.
DATA:
lo_descr TYPE REF TO cl_abap_typedescr.
LOOP AT mt_airplanes INTO lo_plane.
**********************************************************************
* Solution based on RTTI method call
**********************************************************************
lo_descr = cl_abap_typedescr=>describe_by_object_ref( lo_plane ).
IF lo_descr->get_relative_name( ) = 'LCL_CARGO_PLANE'.
lo_cargo ?= lo_plane.
IF rv_max_cargo < lo_cargo->get_cargo( ).
rv_max_cargo = lo_cargo->get_cargo( ).
ENDIF.
514
© Copyright. All rights reserved.
Lesson: Using Runtime Type Identification (RTTI)
ENDIF.
**********************************************************************
* Alternative solution based on condition IS INSTANCE OF
**********************************************************************
*
IF lo_plane IS INSTANCE OF lcl_cargo_plane.
*
lo_cargo ?= lo_plane.
*
IF rv_max_cargo < lo_cargo->get_cargo( ).
*
rv_max_cargo = lo_cargo->get_cargo( ).
*
ENDIF.
*
ENDIF.
**********************************************************************
* Former solution:
* Try to downcast each object and catch those that do not fit.
**********************************************************************
*
TRY.
*
lo_cargo ?= lo_plane.
*
*
IF rv_max_cargo < lo_cargo->get_cargo( ).
*
rv_max_cargo = lo_cargo->get_cargo( ).
*
ENDIF.
*
*
CATCH cx_sy_move_cast_error.
**
plane is not a cargo plane - do nothing
*
ENDTRY.
ENDLOOP.
ENDMETHOD. "get_max_cargo
ENDCLASS. "lcl_carrier IMPLEMENTATION
© Copyright. All rights reserved.
515
Unit 12: Runtime Type Services
LESSON SUMMARY
You should now be able to:
516
●
Explain RTTI
●
Describe structure type properties at runtime
●
Describe object type properties at runtime
© Copyright. All rights reserved.
Unit 12
Learning Assessment
1. Which class is used to identify the attributes of a structure using Run Time Type
Identification?
Choose the correct answer.
X
A CL_ABAP_TYPEDESCR
X
B CL_ABAP_STRUCTDESCR
X
C CL_ABAP_OBJECTDESCR
X
D CL_ABAP_CLASSDESCR
2. Which attribute of CL_ABAP_STRUCTDESCR is used to describe the individual
components of any relevant structure?
Choose the correct answer.
X
A COMPONENTS
X
B TYPE_KIND
X
C LENGTH
X
D DECIMALS
© Copyright. All rights reserved.
517
Unit 12
Learning Assessment - Answers
1. Which class is used to identify the attributes of a structure using Run Time Type
Identification?
Choose the correct answer.
X
A CL_ABAP_TYPEDESCR
X
B CL_ABAP_STRUCTDESCR
X
C CL_ABAP_OBJECTDESCR
X
D CL_ABAP_CLASSDESCR
2. Which attribute of CL_ABAP_STRUCTDESCR is used to describe the individual
components of any relevant structure?
Choose the correct answer.
518
X
A COMPONENTS
X
B TYPE_KIND
X
C LENGTH
X
D DECIMALS
© Copyright. All rights reserved.
UNIT 13
Creation of a Comprehensive
Object-Oriented Application
Lesson 1
Developing a Comprehensive Object-Oriented Application
Exercise 28: Create an UML Class Diagram
Exercise 29: Develop a Comprehensive Object-Oriented Application
520
525
529
UNIT OBJECTIVES
●
Develop a comprehensive object-oriented application
© Copyright. All rights reserved.
519
Unit 13
Lesson 1
Developing a Comprehensive Object-Oriented
Application
LESSON OVERVIEW
This lesson explains about the ways to apply the techniques of ABAP Objects to the case
study.
Business Example
A customer has to book a flight in a travel agency but the flight is already fully booked.
However, the customer is given the option of registering for the flight and being put on the
waiting list. For this reason, you require the following knowledge:
●
An understanding of UML diagrams
●
An understanding of object-oriented programming
LESSON OBJECTIVES
After completing this lesson, you will be able to:
●
520
Develop a comprehensive object-oriented application
© Copyright. All rights reserved.
Lesson: Developing a Comprehensive Object-Oriented Application
Requirements of an Object-Oriented Case Study
Figure 187: Case Study – Requirements I
Using the ABAP objects program, you need to implement the class diagram in the model and
be able to maintain a waitlist for each flight. It is possible to maintain a waiting list for each
flight row from table SFLIGHT with the key CARRID, CONNID, and FLDATE.
Note:
The model shown in the figure is one possible solution to the waiting list
requirements described. The course participants can use their own UML class
diagram, which produces a different solution.
All waiting lists are to be stored in a waiting list buffer called WAIT_LIST, which is technically
an internal table. In addition to the flight data, the waiting lists are to contain a list of all
customers who have registered for this flight. The functions of this application are shown in
the figure.
© Copyright. All rights reserved.
521
Unit 13: Creation of a Comprehensive Object-Oriented Application
Case Study – Requirements II
Figure 188: Case Study – Requirements II
The screen and functions shown are to be created in accordance with the requirement
specifications. The screen layout and flow logic are already available. You now have to
implement the actual flow, that is, the intelligence of the program using object-oriented
techniques.
Functions of Buttons
Table 9: Functions of Buttons
The following table lists the functions of the Buttons used in the case study:
522
Button
Functions
Display
Displays the waiting list for the specified flight (CARRID, CONNID, FLDATE)
Create
Creates the waiting list for the specified flight (CARRID, CONNID, FLDATE)
Delete
Deletes the waiting list for the specified flight (CARRID, CONNID, FLDATE)
Add
Adds the customer selected on the right of the
screen to the flight waiting list selected on the left
Delete (Customer)
Deletes the customer selected on the right of the
screen from the flight displayed on the left
© Copyright. All rights reserved.
Lesson: Developing a Comprehensive Object-Oriented Application
Button
Functions
Position
Displays the selected customer’s position on the
waiting list
Customer Type
Shows whether the selected customer is a private
customer or a business customer (you will find the
relevant information in the CUSTTYPE field of table
SCUSTOM)
Display customers Moved Up
Displays all customers from the list who were successfully moved up from the waiting list to get a seat
on the flight
Status Log
Displays the number of customers from the list who
were successful in getting a seat on a flight
© Copyright. All rights reserved.
523
Unit 13: Creation of a Comprehensive Object-Oriented Application
524
© Copyright. All rights reserved.
Unit 13
Exercise 28
Create an UML Class Diagram
Business Example
A travel agency wants to offer its customers an additional service. If customers want to book
a flight that is already fully booked, they can put their names on a waiting list for this flight. If a
seat becomes free at a later date, a customer from the waiting list can be placed on the flight.
This customer’s name is then removed from the waiting list.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
You can use the following suggestions but you can also choose a model of your own, which
you can then use for an alternate implementation later. Perform the following steps to create
a class diagram.
1. The waiting list must be the central class in the model. Use LCL_WAITLIST as the class
name (ZCL_##_WAITLIST if you are using the Class Builder).
The class must have the public attributes, CARRID, CONNID, FLDATE, and the private
attribute, CUSTOMER_LIST.
The following public methods must be defined in the UML:
CONSTRUCTOR, ADD, DELETE, GET_POS, GET_FIRST and GET_WAIT_LIST.
Hint:
According to the encapsulation concept, you define all the attributes as
private and then access these attributes of the waiting list with external
methods. You need to define the attributes as public to save time and effort.
2. Customers form another class. Use LCL_CUSTOMER as the class name
(ZCL_##_CUSTOMER if you are using the Class Builder).
This class should have the public attribute ID and the private attributes NAME, STREET,
CITY and APP_DATE.
The following public methods should be defined in the UML:
CONSTRUCTOR and GET_ATTRIBUTES.
3. You could simply define the buffer for the waiting lists in the main program as a normal
internal table. However, you want to use one class in this case and therefore the singleton
concept is used.
Define the buffer for the waiting lists as singleton class LCL_BUFFER (ZCL_##_BUFFER if
you are using the Class Builder).
The class must contain the attribute BUFFER_LIST: the private, static attribute
N_O_ENTRIES and a private, static reference to itself.
The following public methods must be defined in the UML:
CLASS_CONSTRUCTOR (as a static method) and DISPLAY_N_O_ENTRIES.
© Copyright. All rights reserved.
525
Unit 13: Creation of a Comprehensive Object-Oriented Application
Hint:
According to the encapsulation concept, you need to define the
BUFFER_LIST attribute as private and then access this attribute with
methods from the main program. In this case, you define this attribute as
public and then access it externally and directly to save time and effort.
If you follow the model solution for the class diagram, you must use methods.
4. Define the relationships between these classes and assign the cardinalities (multiplicity).
You also have the option of mapping the navigation options.
526
© Copyright. All rights reserved.
Unit 13
Solution 28
Create an UML Class Diagram
Business Example
A travel agency wants to offer its customers an additional service. If customers want to book
a flight that is already fully booked, they can put their names on a waiting list for this flight. If a
seat becomes free at a later date, a customer from the waiting list can be placed on the flight.
This customer’s name is then removed from the waiting list.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
You can use the following suggestions but you can also choose a model of your own, which
you can then use for an alternate implementation later. Perform the following steps to create
a class diagram.
1. The waiting list must be the central class in the model. Use LCL_WAITLIST as the class
name (ZCL_##_WAITLIST if you are using the Class Builder).
The class must have the public attributes, CARRID, CONNID, FLDATE, and the private
attribute, CUSTOMER_LIST.
The following public methods must be defined in the UML:
CONSTRUCTOR, ADD, DELETE, GET_POS, GET_FIRST and GET_WAIT_LIST.
Hint:
According to the encapsulation concept, you define all the attributes as
private and then access these attributes of the waiting list with external
methods. You need to define the attributes as public to save time and effort.
a) Refer to the model solution.
2. Customers form another class. Use LCL_CUSTOMER as the class name
(ZCL_##_CUSTOMER if you are using the Class Builder).
This class should have the public attribute ID and the private attributes NAME, STREET,
CITY and APP_DATE.
The following public methods should be defined in the UML:
CONSTRUCTOR and GET_ATTRIBUTES.
a) Refer to the model solution.
3. You could simply define the buffer for the waiting lists in the main program as a normal
internal table. However, you want to use one class in this case and therefore the singleton
concept is used.
Define the buffer for the waiting lists as singleton class LCL_BUFFER (ZCL_##_BUFFER if
you are using the Class Builder).
The class must contain the attribute BUFFER_LIST: the private, static attribute
N_O_ENTRIES and a private, static reference to itself.
© Copyright. All rights reserved.
527
Unit 13: Creation of a Comprehensive Object-Oriented Application
The following public methods must be defined in the UML:
CLASS_CONSTRUCTOR (as a static method) and DISPLAY_N_O_ENTRIES.
Hint:
According to the encapsulation concept, you need to define the
BUFFER_LIST attribute as private and then access this attribute with
methods from the main program. In this case, you define this attribute as
public and then access it externally and directly to save time and effort.
If you follow the model solution for the class diagram, you must use methods.
a) Refer to the model solution.
4. Define the relationships between these classes and assign the cardinalities (multiplicity).
You also have the option of mapping the navigation options.
a) See the model solution.
Figure 189: Waiting List – UML Class Diagram
The figure, Waiting List – UML Class Diagram, is the class diagram model solution for
the Waiting List business example.
528
© Copyright. All rights reserved.
Unit 13
Exercise 29
Develop a Comprehensive Object-Oriented
Application
Business Example
Based on the business model from the previous exercise, you now need to implement the
logic using ABAP Object programs.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Convert the definitions from your class diagram into a program. If you use the suggestions
proposed in this unit, follow the instructions below. If you have created your own alternate
UML class diagram, you can ignore these instructions.
1. Use program SAPBC401_PRJT_WAITLIST as a template. Your program should be called
ZBC401_##_PRJS_WAITLIST.
Copy all Include programs from the template and rename them. You should always use
the target names specified with your group number (suggested name:
ZBC401_##_PRJS_INC_xxx).
2. The copied template already contains the parameters for the application to be created.
Familiarize yourself with the program structure. This program contains a screen on which
buttons for all of the required functions are already provided. However, with the exception
of the buttons in the standard toolbar, these functions still have to be implemented.
For the meaning of the individual buttons, refer to the screen shown in the figure and the
explanatory text in your course notes.
Note:
If you have no experience with dynamic screens or dialog programming with
ABAP, speak to your course instructor.
© Copyright. All rights reserved.
529
Unit 13: Creation of a Comprehensive Object-Oriented Application
Hint:
The display of the customer data on the waiting list function code SHOW is
not part of this exercise. Therefore, to save time, you can use function
module BC401_DISPLAY_DATA. Later, when you are implementing this
function, you should familiarize yourself with its interface and use it for
display. If you have enough time, you can also use the ABAP List Viewer
(ALV) Grid Control.
To simplify the scenario, avoid persistent storage of the waiting list. In other
words, the data is not to be saved to the database.
The focus of this exercise is on the creation of a viable model for which the
existing components should be examined. The main point of the exercise is
not to implement the program in detail.
530
© Copyright. All rights reserved.
Unit 13
Solution 29
Develop a Comprehensive Object-Oriented
Application
Business Example
Based on the business model from the previous exercise, you now need to implement the
logic using ABAP Object programs.
In the exercises for this course, when the input values include ##, replace ## with your group
number.
Convert the definitions from your class diagram into a program. If you use the suggestions
proposed in this unit, follow the instructions below. If you have created your own alternate
UML class diagram, you can ignore these instructions.
1. Use program SAPBC401_PRJT_WAITLIST as a template. Your program should be called
ZBC401_##_PRJS_WAITLIST.
Copy all Include programs from the template and rename them. You should always use
the target names specified with your group number (suggested name:
ZBC401_##_PRJS_INC_xxx).
a) Carry out this step in the usual manner.
2. The copied template already contains the parameters for the application to be created.
Familiarize yourself with the program structure. This program contains a screen on which
buttons for all of the required functions are already provided. However, with the exception
of the buttons in the standard toolbar, these functions still have to be implemented.
For the meaning of the individual buttons, refer to the screen shown in the figure and the
explanatory text in your course notes.
Note:
If you have no experience with dynamic screens or dialog programming with
ABAP, speak to your course instructor.
© Copyright. All rights reserved.
531
Unit 13: Creation of a Comprehensive Object-Oriented Application
Hint:
The display of the customer data on the waiting list function code SHOW is
not part of this exercise. Therefore, to save time, you can use function
module BC401_DISPLAY_DATA. Later, when you are implementing this
function, you should familiarize yourself with its interface and use it for
display. If you have enough time, you can also use the ABAP List Viewer
(ALV) Grid Control.
To simplify the scenario, avoid persistent storage of the waiting list. In other
words, the data is not to be saved to the database.
The focus of this exercise is on the creation of a viable model for which the
existing components should be examined. The main point of the exercise is
not to implement the program in detail.
a) The model solution provided here encapsulates the buffer with the waiting lists in class
LCL_BUFFER. The waiting lists in the buffer can be accessed with public methods.
It is also possible to create the buffer in the main program directly as a nonencapsulated internal table.
Program SAPBC401_PRJS_WAITLIST_1
REPORT sapbc401_prjs_waitlist_1.
INCLUDE sapbc401_prjs_inc_1.
DATA ok_code LIKE sy-ucomm.
TABLES: sdyn_conn, scustom.
TYPES: ty_wait_list TYPE STANDARD TABLE OF
REF TO lcl_waitlist.
DATA:
r_buffer TYPE REF TO lcl_buffer,
r_customer TYPE REF TO lcl_customer,
r_waitlist TYPE REF TO lcl_waitlist,
r_exc TYPE REF TO cx_root.
DATA: wa_sflight TYPE sflight.
LOAD-OF-PROGRAM.
*---------------------------------------------------* Instantiate the Buffer which is a singleton
r_buffer = lcl_buffer=>get_buffer_ref( ).
* some dynpro initializations
sdyn_conn-carrid = 'LH'.
sdyn_conn-connid = '0400'.
sdyn_conn-fldate = '20040710'.
scustom-id = '00003392'.
START-OF-SELECTION.
*---------------------------------------------------CALL SCREEN 100.
532
© Copyright. All rights reserved.
Lesson: Developing a Comprehensive Object-Oriented Application
INCLUDE sapbc401_prjs_waitlist_o01.
Solution - Include Program SAPBC401_PRJS_WAITLIST_I01
*-------------------------------------------------*
* INCLUDE BC401_CSS1_WAITLIST_I01 .
*-------------------------------------------------*
*-------------------------------------------------*
* Module check_and_create_cust INPUT
*-------------------------------------------------*
MODULE check_and_create_cust INPUT.
SELECT SINGLE name street city FROM scustom
INTO CORRESPONDING FIELDS OF scustom
WHERE id = scustom-id.
IF sy-subrc <> 0.
CLEAR: scustom-name, scustom-city.
MESSAGE e916(BC401) WITH scustom-id.
* Customer number & does not exist. Please correct !
ENDIF.
ENDMODULE. " check_and_create_cust INPUT
*-------------------------------------------------*
* Module user_command_0100 INPUT
*-------------------------------------------------*
MODULE user_command_0100 INPUT.
DATA: text TYPE string.
DATA: n_o_lines TYPE i.
DATA: save_ok TYPE sy-ucomm.
CLEAR r_waitlist.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
WHEN 'CREATE'.
TRY.
r_buffer->create_wait_list( EXPORTING
im_carrid = sdyn_conn-carrid
im_connid = sdyn_conn-connid
im_fldate = sdyn_conn-fldate ).
MESSAGE s905(BC401)
WITH sdyn_conn-carrid sdyn_conn-connid sdyn_conn-fldate.
CATCH cx_wait_list INTO r_exc.
text = r_exc->get_text( ).
MESSAGE s901(BC401) WITH sdyn_conn-carrid sdyn_conn-connid.
ENDTRY.
WHEN 'SHOW'.
DATA: it_customer_list TYPE STANDARD TABLE OF bc401_typd_cust.
DATA: wa_cust LIKE LINE OF it_customer_list.
DATA: r_customer_list TYPE TABLE OF REF TO lcl_customer.
© Copyright. All rights reserved.
533
Unit 13: Creation of a Comprehensive Object-Oriented Application
DATA: r_cust TYPE REF TO lcl_customer.
r_waitlist = r_buffer->get_wait_list(
im_carrid = sdyn_conn-carrid
im_connid = sdyn_conn-connid
im_fldate = sdyn_conn-fldate ).
IF r_waitlist IS BOUND.
r_waitlist->get_wait_list( IMPORTING
ex_wait_list = r_customer_list ).
n_o_lines = LINES( r_customer_list ).
IF n_o_lines > 0.
CLEAR it_customer_list.
LOOP AT r_customer_list INTO r_cust.
r_cust->get_attributes( IMPORTING ex_cust = wa_cust ).
INSERT wa_cust INTO TABLE it_customer_list.
ENDLOOP.
* show dynpro with all customers and their data
CALL FUNCTION 'BC401_DISPLAY_DATA'
EXPORTING
im_list = it_customer_list.
ELSE.
MESSAGE s903(BC401)
WITH sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* The waitinglist for flight &1 &2 &3 has no entries !
ENDIF.
ELSE.
MESSAGE s902(BC401) WITH sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* There is no waitinglist for flight Flug &1 &2 &3 !
ENDIF.
WHEN 'DELETE'.
TRY.
r_buffer->delete_wait_list( EXPORTING
im_carrid = sdyn_conn-carrid
im_connid = sdyn_conn-connid
im_fldate = sdyn_conn-fldate ).
MESSAGE s906(BC401) WITH
sdyn_conn-carrid sdyn_conn-connid sdyn_conn-fldate.
* Waitinglist for flight &1 &2 &3 has been deleted
* succesfully
CATCH cx_wait_list INTO r_exc.
text = r_exc->get_text( ).
MESSAGE text TYPE 'S'.
ENDTRY.
WHEN 'FIRST'.
r_waitlist = r_buffer->get_wait_list( im_carrid
= sdyn_conn-carrid
im_connid = sdyn_conn-connid
im_fldate = sdyn_conn-fldate ).
IF r_waitlist IS BOUND.
TRY.
r_waitlist->get_first( ).
534
© Copyright. All rights reserved.
Lesson: Developing a Comprehensive Object-Oriented Application
MESSAGE s907(BC401)
WITH sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* The first customer on waitinglist &1 &2 &3
* has been deleted.
CATCH cx_wait_list INTO r_exc.
text = r_exc->get_text( ).
MESSAGE text TYPE 'I'.
ENDTRY.
ELSE.
MESSAGE s902(BC401) WITH sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* There is no waitinglist for flight &1 &2 &3 !
ENDIF.
WHEN 'ADD'.
IF scustom-id IS INITIAL.
MESSAGE s908(BC401).
* Please enter a correct customernumber !
EXIT.
ENDIF.
r_waitlist = r_buffer->get_wait_list( im_carrid = sdyn_conn-carrid
im_connid = sdyn_conn-connid
im_fldate = sdyn_conn-fldate ).
IF r_waitlist IS BOUND.
TRY.
CREATE OBJECT r_customer EXPORTING im_id = scustom-id
im_name = scustom-name
im_street = scustom-street
im_city = scustom-city
im_app_date = sy-datum.
r_waitlist->add( r_customer ).
MESSAGE s910(BC401)
WITH scustom-id sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* Customer &1 was appended to waitinglist for
* flight &2 &3 &4
CATCH cx_wait_list INTO r_exc.
text = r_exc->get_text( ).
MESSAGE text TYPE 'I'.
ENDTRY.
ELSE.
MESSAGE s902(BC401) WITH sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* There is no waitinglist for flight &1 &2 &3 !
ENDIF.
WHEN 'DEL'.
IF scustom-id IS INITIAL.
MESSAGE s908(BC401).
* Please select a valid customer number !
EXIT.
ENDIF.
r_waitlist = r_buffer->get_wait_list( im_carrid = sdyn_conn-carrid
im_connid = sdyn_conn-connid
© Copyright. All rights reserved.
535
Unit 13: Creation of a Comprehensive Object-Oriented Application
im_fldate = sdyn_conn-fldate ).
IF r_waitlist IS BOUND.
IF NOT r_customer IS BOUND.
MESSAGE s911(BC401).
ELSE.
TRY.
r_waitlist->delete( r_customer ).
MESSAGE s912(BC401)
WITH scustom-id sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* Customer &1 was deleted from waitinglist for flight &2 &3
* &4 !
CATCH cx_wait_list INTO r_exc.
text = r_exc->get_text( ).
MESSAGE text TYPE 'I'.
ENDTRY.
ENDIF.
ELSE.
MESSAGE s902(BC401) WITH sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* There is no waitinglist for flight &1 &2 &3 !
ENDIF.
WHEN 'POS'.
DATA pos LIKE sy-tabix.
DATA flight TYPE string.
DATA fldate(10) TYPE c.
IF scustom-id IS INITIAL.
MESSAGE s908(BC401).
* Please enter a valid customernumber !
EXIT.
ENDIF.
r_waitlist = r_buffer->get_wait_list( im_carrid = sdyn_conn-carrid
im_connid = sdyn_conn-connid
im_fldate = sdyn_conn-fldate ).
IF r_waitlist IS BOUND.
TRY.
CREATE OBJECT r_customer EXPORTING im_id = scustom-id
im_name = scustom-name
im_street = scustom-street
im_city = scustom-city
im_app_date = sy-datum.
r_waitlist->get_pos( EXPORTING im_customer = r_customer
IMPORTING ex_pos = pos ).
WRITE sdyn_conn-fldate TO fldate.
CONCATENATE sdyn_conn-carrid sdyn_conn-connid fldate
INTO flight SEPARATED BY space.
MESSAGE i913(BC401) WITH scustom-id flight pos.
* Customer &1 is held on list for flight &2 at position &3
CATCH cx_wait_list INTO r_exc.
text = r_exc->get_text( ).
MESSAGE text TYPE 'I'.
ENDTRY.
536
© Copyright. All rights reserved.
Lesson: Developing a Comprehensive Object-Oriented Application
ELSE.
MESSAGE s902(BC401) WITH sdyn_conn-carrid sdyn_conn-connid
sdyn_conn-fldate.
* There is no waitinglist for flight &1 &2 &3 !
ENDIF.
ENDCASE.
ENDMODULE. " user_command_0100 INPUT
*--------------------------------------------------*
* Module check_flight INPUT
*--------------------------------------------------*
MODULE check_flight INPUT.
SELECT SINGLE * FROM sflight INTO wa_sflight
WHERE carrid = sdyn_conn-carrid
AND connid = sdyn_conn-connid
AND fldate = sdyn_conn-fldate.
IF sy-subrc <> 0.
MESSAGE e904(BC401).
* Please select a valid flight !
ENDIF.
ENDMODULE.
*--------------------------------------------------*
* Module exit INPUT
*--------------------------------------------------*
MODULE exit INPUT.
CASE ok_code.
WHEN 'CANCEL'.
CLEAR: scustom, sdyn_conn.
LEAVE TO SCREEN 100.
WHEN 'EXIT'.
LEAVE PROGRAM.
ENDCASE.
ENDMODULE. " exit INPUT
Solution - Include Program SAPBC401_PRJS_WAITLIST_O01
*-------------------------------------------------*
* Include SAPBC401_PRJS_WAITLIST_O01
*-------------------------------------------------*
*-------------------------------------------------*
* Module STATUS_0100 OUTPUT
*-------------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'DYNPRO_100'.
SET TITLEBAR 'TITLE_100'.
ENDMODULE. " STATUS_0100 OUTPUT
*-----------------------------------------------*
* Module clear_ok_code OUTPUT
*-----------------------------------------------*
MODULE clear_ok_code OUTPUT.
CLEAR ok_code.
ENDMODULE.
" clear_ok_code OUTPUT
© Copyright. All rights reserved.
537
Unit 13: Creation of a Comprehensive Object-Oriented Application
Solution - Include Program SAPBC401_PRJS_INC_1
*--------------------------------------------------*
* Include SAPBC401_PRJS_INC_1
*--------------------------------------------------*
*--------------------------------------------------*
* CLASS lcl_customer DEFINITION
*--------------------------------------------------*
CLASS lcl_customer DEFINITION.
PUBLIC SECTION.
METHODS constructor IMPORTING im_id TYPE s_customer
im_name TYPE s_custname
im_street TYPE s_street
im_city TYPE city
im_app_date TYPE d.
METHODS: get_attributes EXPORTING ex_cust
TYPE bc401_typd_cust.
DATA: id TYPE s_customer READ-ONLY.
PRIVATE SECTION.
DATA:
name TYPE s_custname,
street TYPE s_street,
city TYPE city,
app_date TYPE d.
ENDCLASS. "lcl_customer DEFINITION
*---------------------------------------------------*
* CLASS lcl_customer IMPLEMENTATION
*---------------------------------------------------*
CLASS lcl_customer IMPLEMENTATION.
METHOD constructor.
id = im_id.
name = im_name.
street = im_street.
city = im_city.
app_date = im_app_date.
ENDMETHOD. "constructor
METHOD get_attributes.
ex_cust-id = id.
ex_cust-name = name.
ex_cust-street = street.
ex_cust-city = city.
ex_cust-app_date = app_date.
ENDMETHOD. "get_attributes
ENDCLASS. "lcl_customer IMPLEMENTATION
*---------------------------------------------------*
* CLASS lcl_waitlist DEFINITION
*---------------------------------------------------*
CLASS lcl_waitlist DEFINITION.
PUBLIC SECTION.
TYPES ty_customer_list TYPE
STANDARD TABLE OF REF TO lcl_customer WITH
DEFAULT KEY.
538
© Copyright. All rights reserved.
Lesson: Developing a Comprehensive Object-Oriented Application
METHODS constructor IMPORTING
im_carrid TYPE sflight-carrid
im_connid TYPE sflight-connid
im_fldate TYPE sflight-fldate.
METHODS add IMPORTING im_customer TYPE
REF TO lcl_customer
RAISING cx_wait_list.
METHODS delete IMPORTING im_customer
TYPE REF TO lcl_customer
RAISING cx_wait_list.
METHODS get_pos IMPORTING im_customer
TYPE REF TO lcl_customer
EXPORTING ex_pos LIKE sy-tabix
RAISING cx_wait_list.
METHODS get_wait_list EXPORTING ex_wait_list
TYPE ty_customer_list.
METHODS get_first RAISING cx_wait_list.
DATA:
carrid TYPE sflight-carrid READ-ONLY,
connid TYPE sflight-connid READ-ONLY,
fldate TYPE sflight-fldate READ-ONLY.
PRIVATE SECTION.
DATA: customer_list TYPE ty_customer_list.
ENDCLASS. "lcl_waitlist DEFINITION
*------------------------------------------*
* CLASS lcl_waitlist IMPLEMENTATION
*------------------------------------------*
CLASS lcl_waitlist IMPLEMENTATION.
METHOD constructor.
carrid = im_carrid.
connid = im_connid.
fldate = im_fldate.
ENDMETHOD.
"constructor
METHOD get_wait_list.
ex_wait_list = customer_list.
ENDMETHOD. "get_wait_list
METHOD add.
READ TABLE customer_list WITH KEY
table_line->id = im_customer->id TRANSPORTING NO FIELDS.
*** customer is not in wait_list
IF sy-subrc <> 0.
INSERT im_customer INTO TABLE customer_list.
ELSE.
*** customer is already in wait_list for this flight
RAISE EXCEPTION TYPE cx_wait_list
EXPORTING
textid
= cx_wait_list=>cx_wait_list_customer_there
customer = im_customer->id
carrid
= carrid
connid
= connid
© Copyright. All rights reserved.
539
Unit 13: Creation of a Comprehensive Object-Oriented Application
fldate
ENDIF.
= fldate.
ENDMETHOD.
"add
METHOD get_first.
DATA r_cust TYPE REF TO lcl_customer.
READ TABLE customer_list INTO r_cust INDEX 1.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE cx_wait_list
EXPORTING
textid = cx_wait_list=>cx_wait_list_no_entry
carrid = carrid
connid = connid
fldate = fldate.
ELSE.
DELETE customer_list INDEX 1.
ENDIF.
ENDMETHOD. "get_first
METHOD delete.
DELETE customer_list
WHERE table_line->id = im_customer->id.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE cx_wait_list
EXPORTING
textid = cx_wait_list=>cx_wait_list_customer_notthere
customer = im_customer->id
carrid = carrid
connid = connid
fldate = fldate.
ENDIF.
ENDMETHOD. "delete
METHOD get_pos.
READ TABLE customer_list
WITH KEY table_line->id = im_customer->id
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
ex_pos = sy-tabix.
ELSE.
RAISE EXCEPTION TYPE cx_wait_list
EXPORTING
textid = cx_wait_list=>cx_wait_list_customer_notthere
customer = im_customer->id
carrid = carrid
connid = connid
fldate = fldate.
ENDIF.
ENDMETHOD. "get_pos
*-------------------------------------------------* CLASS lcl_buffer DEFINITION
*-------------------------------------------------* implemented as SINGLETON, should exist only once
*-------------------------------------------------CLASS lcl_buffer DEFINITION CREATE PRIVATE.
540
© Copyright. All rights reserved.
Lesson: Developing a Comprehensive Object-Oriented Application
PUBLIC SECTION.
CLASS-METHODS: class_constructor.
CLASS-METHODS: get_buffer_ref RETURNING value(re_buffer)
TYPE REF TO lcl_buffer.
METHODS: create_wait_list IMPORTING
im_carrid TYPE s_carr_id
im_connid TYPE s_conn_id
im_fldate TYPE sflight-fldate
RETURNING value(re_waitlist)
TYPE REF TO lcl_waitlist
RAISING cx_wait_list.
METHODS: get_wait_list IMPORTING
im_carrid TYPE s_carr_id
im_connid TYPE s_conn_id
im_fldate TYPE sflight-fldate
RETURNING value(re_waitlist)
TYPE REF TO lcl_waitlist.
METHODS: delete_wait_list IMPORTING
im_carrid TYPE s_carr_id
im_connid TYPE s_conn_id
im_fldate TYPE sflight-fldate
RAISING cx_wait_list.
METHODS: delete_all_wait_lists.
PRIVATE SECTION.
CLASS-DATA: r_buffer TYPE REF TO lcl_buffer.
DATA: wait_list TYPE STANDARD TABLE OF
REF TO lcl_waitlist.
ENDCLASS. "lcl_buffer DEFINITION
*-------------------------------------------------* CLASS lcl_buffer IMPLEMENTATION
*-------------------------------------------------CLASS lcl_buffer IMPLEMENTATION.
METHOD class_constructor.
CREATE OBJECT r_buffer.
ENDMETHOD. "class_constructor
METHOD get_buffer_ref.
re_buffer = r_buffer.
ENDMETHOD. "get_buffer_ref
METHOD create_wait_list.
DATA: r_waitlist TYPE REF TO lcl_waitlist.
r_waitlist = get_wait_list( im_carrid = im_carrid
im_connid = im_connid
im_fldate = im_fldate ).
IF NOT r_waitlist IS BOUND.
CREATE OBJECT r_waitlist
EXPORTING
im_carrid = im_carrid
im_connid = im_connid
© Copyright. All rights reserved.
541
Unit 13: Creation of a Comprehensive Object-Oriented Application
im_fldate = im_fldate.
INSERT r_waitlist INTO TABLE wait_list.
ELSE.
RAISE EXCEPTION TYPE cx_wait_list
EXPORTING
carrid = im_carrid
connid = im_connid
fldate = im_fldate
textid = cx_wait_list=>cx_wait_list_exists.
ENDIF.
ENDMETHOD.
"create_wait_list
METHOD get_wait_list.
READ TABLE wait_list INTO re_waitlist WITH KEY
table_line->carrid = im_carrid
table_line->connid = im_connid
table_line->fldate = im_fldate.
ENDMETHOD.
"get_wait_list
METHOD delete_wait_list.
DATA: r_waitlist TYPE REF TO lcl_waitlist.
r_waitlist = get_wait_list( im_carrid = im_carrid
im_connid = im_connid
im_fldate = im_fldate ).
IF NOT r_waitlist IS BOUND.
RAISE EXCEPTION TYPE cx_wait_list
EXPORTING
carrid = im_carrid
connid = im_connid
fldate = im_fldate.
ELSE.
DELETE wait_list
WHERE table_line->carrid = im_carrid
AND table_line->connid = im_connid
AND table_line->fldate = im_fldate.
ENDIF.
ENDMETHOD. "delete_wait_list
METHOD delete_all_wait_lists.
CLEAR wait_list.
*ATTENTION: in our case, this also deletes all
*customer-objects.
* --> COMPOSITION in class-diagram ?
ENDMETHOD.
"delete_all_wait_lists
ENDCLASS. "lcl_buffer IMPLEMENTATION
Flow Logic of Screen 100
PROCESS BEFORE OUTPUT.
MODULE status_0100.
MODULE clear_ok_code.
PROCESS AFTER INPUT.
MODULE exit AT EXIT-COMMAND.
CHAIN.
FIELD: sdyn_conn-carrid,
sdyn_conn-connid,
542
© Copyright. All rights reserved.
Lesson: Developing a Comprehensive Object-Oriented Application
sdyn_conn-fldate.
MODULE check_flight.
ENDCHAIN.
CHAIN.
FIELD: scustom-id,
scustom-name,
scustom-city.
MODULE check_and_create_cust. " ON CHAIN-REQUEST.
ENDCHAIN.
MODULE user_command_0100.
© Copyright. All rights reserved.
543
Unit 13: Creation of a Comprehensive Object-Oriented Application
LESSON SUMMARY
You should now be able to:
●
544
Develop a comprehensive object-oriented application
© Copyright. All rights reserved.
Unit 13
Learning Assessment
1. In the case study, when we use one class to define the buffer for the waiting lists for all
flights, what concept are we implementing?
Choose the correct answer.
X
A Superclass
X
B Singleton class
X
C Subclass
X
D Friends
© Copyright. All rights reserved.
545
Unit 13
Learning Assessment - Answers
1. In the case study, when we use one class to define the buffer for the waiting lists for all
flights, what concept are we implementing?
Choose the correct answer.
546
X
A Superclass
X
B Singleton class
X
C Subclass
X
D Friends
© Copyright. All rights reserved.
Download