TAW12_1 - ABAP Workbench Concept
January 9, 2017 | Author: manikandanu1 | Category: N/A
Short Description
Download TAW12_1 - ABAP Workbench Concept...
Description
TAW12_1 ABAP Workbench Concepts - Part 1
.
.
PARTICIPANT HANDBOOK INSTRUCTOR-LED TRAINING . Course Version: 10 Course Duration: 5 Day(s) Material Number: 50117660
SAP Copyrights and Trademarks © 2013 SAP AG. 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 AG. The information contained herein may be changed without prior notice. Some software products marketed by SAP AG and its distributors contain proprietary software components of other software vendors. ●
Microsoft, Windows, Excel, Outlook, and PowerPoint are registered trademarks of Microsoft Corporation.
●
IBM, DB2, DB2 Universal Database, System i, System i5, System p, System p5, System x, System z, System z10, System z9, z10, z9, iSeries, pSeries, xSeries, zSeries, eServer, z/VM, z/OS, i5/OS, S/390, OS/390, OS/400, AS/400, S/390 Parallel Enterprise Server, PowerVM, Power Architecture, POWER6+, POWER6, POWER5+, POWER5, POWER, OpenPower, PowerPC, BatchPipes, BladeCenter, System Storage, GPFS, HACMP, RETAIN, DB2 Connect, RACF, Redbooks, OS/2, Parallel Sysplex, MVS/ESA, AIX, Intelligent Miner, WebSphere, Netfinity, Tivoli and Informix are trademarks or registered trademarks of IBM Corporation.
●
Linux is the registered trademark of Linus Torvalds in the U.S. and other countries.
●
Adobe, the Adobe logo, Acrobat, PostScript, and Reader are either trademarks or registered trademarks of Adobe Systems Incorporated in the United States and/or other countries.
●
Oracle is a registered trademark of Oracle Corporation
●
UNIX, X/Open, OSF/1, and Motif are registered trademarks of the Open Group.
●
Citrix, ICA, Program Neighborhood, MetaFrame, WinFrame, VideoFrame, and MultiWin are trademarks or registered trademarks of Citrix Systems, Inc.
●
HTML, XML, XHTML and W3C are trademarks or registered trademarks of W3C®, World Wide Web Consortium, Massachusetts Institute of Technology.
●
●
Java is a registered trademark of Sun Microsystems, Inc. JavaScript is a registered trademark of Sun Microsystems, Inc., used under license for technology invented and implemented by Netscape.
●
SAP, R/3, SAP NetWeaver, Duet, PartnerEdge, ByDesign, SAP BusinessObjects Explorer, StreamWork, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries.
●
Business Objects and the Business Objects logo, BusinessObjects, Crystal Reports, Crystal Decisions, Web Intelligence, Xcelsius, and other Business Objects products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of Business Objects Software Ltd. Business Objects is an SAP company.
●
Sybase and Adaptive Server, iAnywhere, Sybase 365, SQL Anywhere, and other Sybase products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of Sybase, Inc. Sybase is an SAP company.
All other product and service names mentioned are the trademarks of their respective companies. Data contained in this document serves informational purposes only. National product specifications may vary.
These materials are subject to change without notice. These materials are provided by SAP AG and its affiliated companies ("SAP Group") for informational purposes only, without representation or warranty of any kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP Group 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.
© Copyright . All rights reserved.
iii
iv
© Copyright . All rights reserved.
About This Handbook This handbook is intended to complement the instructor-led presentation of this course, and serve as a source of reference. It is not suitable for self-study. 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.
v
vi
© Copyright . All rights reserved.
Contents xi
Course Overview
1
Unit 1:
Introduction to Object-Oriented Programming
2 13
Lesson: Explaining the Object-Oriented Programming Model Lesson: Analyzing and Designing with Unified Modeling Language (UML)
25
Exercise 1: Create UML Diagrams
35
Unit 2:
37 51 58 65 69 75 81 85 92 95 113
Lesson: Creating Local Classes Exercise 2: Create Local Classes Lesson: Creating and Working with 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:
114 123 134 137 142 147 154 157 175 176 181 191 195 202 205
Fundamental Object-Oriented Syntax
Inheritance and Casting Lesson: Implementing Inheritance Exercise 7: Implement Inheritance Lesson: Implementing Up-Casts Using Inheritance Exercise 8: Implement Up-Casts Lesson: Implementing Polymorphism Using Inheritance Exercise 9: Implement Polymorphism Using Inheritance Lesson: Implementing Down-Casts Using Inheritance Exercise 10: Implement Down-Casts
Unit 4:
Interfaces and Casting Lesson: Defining and Implementing Local Interfaces Exercise 11: Define and Implement a Local Interface Lesson: Implement Polymorphism Using Interfaces Exercise 12: Implement Polymorphism Using Interfaces Lesson: Joining Classmodels Using Interfaces Exercise 13: Integrate Class Models Using Interfaces
© Copyright . All rights reserved.
vii
223
Unit 5:
224 233 246
Lesson: Implementing Events in Local Classes Exercise 14: Implement Events in Local Classes Lesson: Implementing Events in Local Interfaces
247
Exercise 15: Implement Event Handling for Interfaces
261
Unit 6:
Object-Oriented Repository Objects
262 273 280
Lesson: Creating Global Classes Exercise 16: Implement a Global Class Lesson: Defining and Implementing Global Interfaces
285 294 301
Exercise 17: Import and Implement a Global Interface Lesson: Implementing Inheritance in Global Classes Exercise 18: Implement Inheritance in Global Classes
311
Unit 7:
312 319 325 334 345
387
Unit 8:
448 467
Object-Oriented Design Patterns Lesson: Implementing Special Object-Oriented Techniques Lesson: Implementing the Singleton Pattern Exercise 21: Implement the Singleton Pattern Lesson: Implementing Factory Classes Using Friendship Exercise 22: Implement a Factory Class Using Friendship
Unit 9:
388 395 403 418 427 447
ABAP Object-Oriented Examples Lesson: Implementing ABAP List Viewer (ALV) Exercise 19: Implement the ALV Grid Control Exercise 20: Implement a Popup with the ALV Grid Control Lesson: Implementing Business Add-Ins (BAdIs)
346 354 359 368 371
viii
Object-Oriented Events
Object-Oriented Exception Handling Lesson: Explaining Class-Based Exception Handling Lesson: Defining and Raising Exceptions Exercise 23: Implement Class-Based Exceptions Lesson: Implementing Advanced Exception Handling Techniques Exercise 24: Map Exceptions to Each Other
Unit 10:
Program Calls and Memory Management Lesson: Using Shared Objects Exercise 25: Use Shared Objects
© Copyright . All rights reserved.
477
Unit 11:
Dynamic Programming
478 485
Lesson: Using Generic Data Types Exercise 26: Use Dynamically Typed Field Symbols in Dynamic SQL Statements
495 504
Exercise 27: Access Structure Components Dynamically Lesson: Describing Data Types, Data Objects, and Objects at Runtime Exercise 28: Provide Column Headers Using Runtime Type Identification Lesson: Creating Data Types, Data Objects, and Objects at Runtime Exercise 29: Create Data Objects at Runtime Exercise 30: Create Data Types at Runtime with Runtime Type Creation (RTTC)
517 528 535 545
© Copyright . All rights reserved.
ix
x
© Copyright . All rights reserved.
Course Overview TARGET AUDIENCE This course is intended for the following audiences: ●
Development Consultant
●
Technology Consultant
●
Developer
© Copyright . All rights reserved.
xi
xii
© 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
13 25
UNIT OBJECTIVES ●
Differentiate between procedural and object-oriented programming models
●
Describe ABAP Objects
●
Classify objects
●
Model objects and classes 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: ●
Differentiate between procedural and object-oriented programming models
●
Describe ABAP Objects
History of Selected Programming Languages
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, object-oriented programming (like the Simula 67 programming language), and the logical and procedural programming models (as used in languages like 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 like COBOL and Pascal. ABAP was then extended to form ABAP Objects. Therefore, ABAP Objects unites objectoriented and procedural elements in one programming language. For the object-oriented 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. Encapsulation of Data Using Function Groups
Figure 4: Encapsulating Data Using Function Groups
4
© Copyright . All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
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. Function Groups
Figure 5: Example of a Function Group
The fictional 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.
© Copyright . All rights reserved.
5
Unit 1: Introduction to Object-Oriented Programming
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.
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.
6
© Copyright . All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
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. 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.
© Copyright . All rights reserved.
7
Unit 1: Introduction to Object-Oriented Programming
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. 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 like 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 in ABAP Objects compared to other object-oriented languages are in 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.
8
© Copyright . All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
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 upwardly 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: However, it is also advisable to avoid obsolete statements in the purely procedural environment, since it creates safer and more flexible source code. Nevertheless, because the language is upwardly 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.
© Copyright . All rights reserved.
9
Unit 1: Introduction to Object-Oriented Programming
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 at least 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.
10
© Copyright . All rights reserved.
Lesson: Explaining the Object-Oriented Programming Model
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. The objects react when the event is triggered.
Features of Object-Oriented ABAP The key characteristics of the object-oriented programming model of ABAP Objects are as follows: ●
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.
The advantages of the object-oriented programming model compared to the procedural programming model are as follows:
© Copyright . All rights reserved.
11
Unit 1: Introduction to Object-Oriented Programming
●
Improved software structure and consistency in the development process
●
Reduced maintenance effort and less susceptibility to errors
●
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, you should use modeling language or tools to standardize the analysis and design phase. LESSON SUMMARY You should now be able to:
12
●
Differentiate between procedural and object-oriented programming models
●
Describe ABAP Objects
© Copyright . All rights reserved.
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: ●
Classify objects
●
Model objects and classes in UML
© Copyright . All rights reserved.
13
Unit 1: Introduction to Object-Oriented Programming
Classifying 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, ..., series 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 completely 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.
14
© Copyright . All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
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, 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. Comparing Classes and Objects
Figure 17: Comparing Classes and Objects
© Copyright . All rights reserved.
15
Unit 1: Introduction to Object-Oriented Programming
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.
UML Diagrams The different diagram types in UML represent different views of a system. Three important diagram types that represent different views of a system are as follows: ●
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 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. For example, you can bundle software components into packages according to the structure’s specification in a Component diagram.
16
© Copyright . All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
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. Example of a Class Diagram
Figure 19: An Example of a Class Diagram
A class diagram describes all static relationships between the classes.
© Copyright . All rights reserved.
17
Unit 1: Introduction to Object-Oriented Programming
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. 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.
18
© Copyright . All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
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: ● You must represent an association between class symbols by drawing a line between them. ●
●
●
●
You must 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. 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 of the association lines to describe the relationships between the classes involved. In the example, a person could appear in the role of an employee or in the role of a company director, for example. In the recursive association shown in the example, 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.
19
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.
20
© 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 labelled 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 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 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.
21
Unit 1: Introduction to Object-Oriented Programming
Object Diagram
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.
Sequence Diagram
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.
22
© Copyright . All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
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. 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.
© Copyright . All rights reserved.
23
Unit 1: Introduction to Object-Oriented Programming
24
© 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. Task 1 1. Create a UML class diagram containing the following classes: Class Name
Description
LCL_CARRIER
For the Airline Companies
LCL_AIRPLANE
For the Airline Companies
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. Task 2 As a modeler, decide whether the object diagrams in this unit are correct. 1. The figure shows a class diagram. Eight object diagrams are drawn for this class diagram. Decide whether each object diagram is correct and mark the corresponding checkbox to indicate your answer.
© Copyright . All rights reserved.
25
Unit 1: Introduction to Object-Oriented Programming
Figure 29: Possible Object Diagrams (1)
See more diagrams in the figure (Possible Object Diagrams (2).
Figure 30: Possible Object Diagrams (2)
26
© 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. Task 1 1. Create a UML class diagram containing the following classes: Class Name
Description
LCL_CARRIER
For the Airline Companies
LCL_AIRPLANE
For the Airline Companies
LCL_PASSENGER_PLANE
For Passenger Planes
LCL_CARGO_PLANE
For Cargo Planes
a) Use the model solution as a guide. 2. Create appropriate attributes and methods for each class. a) Be sure to 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.
27
Unit 1: Introduction to Object-Oriented Programming
Figure 28: Class Diagram for Exercise - CARRIER/AIRPLANE
Task 2 As a modeler, decide whether the object diagrams in this unit are correct. 1. The figure shows a class diagram. Eight object diagrams are drawn for this class diagram. Decide whether each object diagram is correct and mark the corresponding checkbox to indicate your answer.
28
© Copyright . All rights reserved.
Lesson: Analyzing and Designing with Unified Modeling Language (UML)
Figure 29: Possible Object Diagrams (1)
See more diagrams in the figure (Possible Object Diagrams (2).
Figure 30: Possible Object Diagrams (2)
a) The object diagrams numbered 2, 4, 5, 6, and 8 are correct.
© Copyright . All rights reserved.
29
Unit 1: Introduction to Object-Oriented Programming
LESSON SUMMARY You should now be able to:
30
●
Classify objects
●
Model objects and classes 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. When the main program calls a function module, only this function module is loaded into the internal session. Determine whether this statement is true or false. X
True
X
False
3. 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
4. Which of the following describes how instances of different classes respond differently to the same messages? Choose the correct answer. X
A Inheritance
X
B Polymorphism
X
C Encapsulation
X
D Event control
© Copyright . All rights reserved.
31
Unit 1: Learning Assessment
5. 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
6. The ______________ diagram pays particular attention to the sequence in which the objects relate to each other. Choose the correct answer. X
A class
X
B behavior
X
C component
X
D object
7. You can group all characteristics and behaviors of similar objects into one central class. Determine whether this statement is true or false.
32
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. When the main program calls a function module, only this function module is loaded into the internal session. Determine whether this statement is true or false. X
True
X
False
3. 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
© Copyright . All rights reserved.
33
Unit 1: Learning Assessment - Answers
4. Which of the following describes how instances of different classes respond differently to the same messages? Choose the correct answer. X
A Inheritance
X
B Polymorphism
X
C Encapsulation
X
D Event control
5. 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
6. The ______________ diagram pays particular attention to the sequence in which the objects relate to each other. Choose the correct answer. X
A class
X
B behavior
X
C component
X
D object
7. 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 2
Fundamental Object-Oriented Syntax
Lesson 1 Creating Local Classes Exercise 2: Create Local Classes
37 51
Lesson 2 Creating and Working with Objects Exercise 3: Create Objects
58 65
Lesson 3 Accessing Methods and Attributes Exercise 4: Call Methods
69 75
Lesson 4 Implementing Constructors in Local Classes Exercise 5: Create and Use Constructors
81 85
Lesson 5 Implementing Class Constructors in Local Classes Exercise 6: Create and Use Static Constructors
92 95
UNIT OBJECTIVES ●
Define local classes
●
Define attributes
●
Create methods
●
Create objects
●
Handle objects
●
Call instance methods
© Copyright . All rights reserved.
35
Unit 2: Fundamental Object-Oriented Syntax
36
●
Call static methods
●
Call functional methods
●
Access public attributes
●
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 and private components. You can access public components, such as
© Copyright . All rights reserved.
37
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 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: A class is a set of objects that have the same structure and exhibit the same behavior.
●
●
●
●
38
A class provides a blueprint for all objects created in the 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 Class Attributes
Figure 33: An Example of Attributes
Attributes contain the data that can be stored in the objects of a class. The types of class attributes are as follows: ● Elementary ●
Structured
●
Table-type
Attributes can consist of data types (local or global) or reference types. 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.
39
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, SYUNAME, 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.
40
© 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.
41
Unit 2: Fundamental Object-Oriented Syntax
Accessing Private Attributes
Figure 36: Accessing Private Attributes
Private attributes are defined in the PRIVATE SECTION of a class. Public attributes are defined in the PUBLIC SECTION of a class. It is syntactically impossible to access private attributes directly from outside. However, 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, if the MAKE and MODEL attributes are public, it will be quite risky because the user may forget to supply the attributes or specify inconsistent attributes. To implement 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 but you must then give them the READ-ONLY addition.
42
© 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.
43
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 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 determine the number of created instances from the system.
44
© 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 One return value can be defined in the method using the RETURN parameter. When using a RETURNING parameter you cannot use EXPORTING and CHANGING simultaneously. You can also use the RETURNING parameter to define functional methods. 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 necessarily need to transfer 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. As of SAP AS 6.10, you can use the RAISING addition in
© Copyright . All rights reserved.
45
Unit 2: Fundamental Object-Oriented Syntax
place of EXCEPTIONS to propagate class-based exceptions. The caller then handles these classbased exceptions without evaluating the SY-SUBRC return value.
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.
46
© 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 directly access private methods from outside. However, a private method can be called by a public method. In the example shown in the figure, 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.
47
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. However, you can only access static components in the implementation section. This means that static methods do not need instances and can be directly accessed through the class.
In the example shown in the figure, you can only access the N_O_VEHICLES static attribute within the GET_N_O_VEHICLES static method. All other attributes are instance attributes and can only appear within instance methods. Technical literature refers to static methods as “class methods” (compared to the CLASSMETHODS syntax element). In ABAP Objects, the official term is “static method”, as it is in C++ and Java.
48
© Copyright . All rights reserved.
Lesson: Creating Local Classes
Comparison of UML Class Diagram with Implementation
Figure 43: Visibility Sections and UML Notation
A Unified Modeling Language (UML) class diagram lists the class name, class attributes, and methods. The components in a class are shown in a UML 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.
49
Unit 2: Fundamental Object-Oriented Syntax
50
© 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. Template: None Solution: SAPBC401_BAS_S1 Task 1 Create an executable program without a TOP include (suggested name:ZBC401_##_MAIN where ## is your 2-digit group number). Task 2 Declare and implement a class for airplanes. 1. Within your program, declare the local class LCL_AIRPLANE. 2. Define the following attributes, Attribute Name/description
Data type
Attribute Type
MV_NAME (name of airplane)
STRING
Private instance attribute
MV_PLANETYPE (type of airplane)
SAPLANE-PLANETYPE Private instance attribute
GV_N_O_AIRPLANES (instance counter) I
Private static attribute
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. Implement the method in such a way that the two instance attributes are set. 4. Define the public instance method DISPLAY_ATTRIBUTES for displaying private instance attributes. Implement the method in such a way that the values of the two instance attributes are output as an ABAP list. You can also output icons if the ICON type group is loaded.
© Copyright . All rights reserved.
51
Unit 2: Fundamental Object-Oriented Syntax
Hint: To load the type group, use the statement TYPE-POOLS icon.
Note: In adherence to the delegation principle, the reading of attribute values and their output is not implemented in the same method. However, because of time constraints, you can ignore the delegation principle for this exercise. 5. Define the public static method DISPLAY_N_O_AIRPLANES to display the private static attribute. Implement the method 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 if you want to omit the counter for now, or if you want to temporarily control increments using the SET_ATTRIBUTES method. 6. 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 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.
52
© 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. Template: None Solution: SAPBC401_BAS_S1 Task 1 Create an executable program without a TOP include (suggested name:ZBC401_##_MAIN where ## is your 2-digit group number). Task 2 Declare and implement a class for airplanes. 1. Within your program, declare the local class LCL_AIRPLANE. a) See the source code extract from the model solution. 2. Define the following attributes, Attribute Name/description
Data type
Attribute Type
MV_NAME (name of airplane)
STRING
Private instance attribute
MV_PLANETYPE (type of airplane)
SAPLANE-PLANETYPE Private instance attribute
GV_N_O_AIRPLANES (instance counter) I
Private static attribute
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. Implement the method in such a way that the two instance attributes are set. a) See the source code extract from the model solution. 4. Define the public instance method DISPLAY_ATTRIBUTES for displaying private instance attributes. Implement the method in such a way that the values of the two instance attributes are output as an ABAP list. You can also output icons if the ICON type group is loaded.
© Copyright . All rights reserved.
53
Unit 2: Fundamental Object-Oriented Syntax
Hint: To load the type group, use the statement TYPE-POOLS icon.
Note: In adherence to the delegation principle, the reading of attribute values and their output is not implemented in the same method. However, because of time constraints, you can ignore the delegation principle for this exercise. a) See the source code extract from the model solution. 5. Define the public static method DISPLAY_N_O_AIRPLANES to display the private static attribute. Implement the method 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 if you want to omit the counter for now, or if you want to temporarily control increments using the SET_ATTRIBUTES method. a) See the source code extract from the model solution. 6. 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 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. Solution: SAPBC401_BAS_S1 REPORT sapbc401_bas_s1. TYPE-POOLS icon. *--------------------------------------------------------* * CLASS lcl_airplane DEFINITION * *--------------------------------------------------------* CLASS lcl_airplane DEFINITION.
54
© Copyright . All rights reserved.
Lesson: Creating Local Classes
PUBLIC SECTION. METHODS: set_attributes IMPORTING iv_name TYPE string iv_planetype TYPE saplane-planetype, display_attributes. CLASS-METHODS: display_n_o_airplanes. PROTECTED SECTION. 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_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. DATA: lv_weight TYPE saplane-weight, lv_cap TYPE saplane-tankcap. 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.
© Copyright . All rights reserved.
55
Unit 2: Fundamental Object-Oriented Syntax
ENDMETHOD. "display_n_o_airplanes ENDCLASS. "lcl_airplane IMPLEMENTATION
56
© 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.
57
Unit 2 Lesson 2 Creating and Working with Objects
LESSON OVERVIEW This lesson explains the concept of creating and handling 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 the following knowledge: ●
An understanding of how to create objects
●
An understanding of how to handle objects
LESSON OBJECTIVES After completing this lesson, you will be able to: ●
Create objects
●
Handle 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 the memory.
58
© Copyright . All rights reserved.
Lesson: Creating and Working with 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 run time instances of classes. Definition of Reference Variables
Figure 45: Definition of Reference Variables
To define a reference variable, use the DATA go_vehicle1 TYPE REF TO lcl_vehicle, which is typed as a pointer to objects of type lcl_vehicle. The null reference is the initial value of a reference variable.
© Copyright . All rights reserved.
59
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 VALUE specification. Reference Semantics of Object References
Figure 47: Reference Semantics of Object References
Object reference variables can be assigned to each other. The figure illustrates an example in which, after the MOVE statement, GO_VEHICLE1 and GO_VEHICLE2 point to the same object.
60
© Copyright . All rights reserved.
Lesson: Creating and Working with Objects
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 r_obj contains the null reference or does not point to any object.
© Copyright . All rights reserved.
61
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
62
© Copyright . All rights reserved.
Lesson: Creating and Working with 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.
63
Unit 2: Fundamental Object-Oriented Syntax
64
© 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. Template: SAPBC401_BAS_S1 Solution: SAPBC401_BAS_S2 Task 1 Define a reference variable. 1. Complete your ZBC401_##_MAIN program or copy the model solution from the previous exercise. 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.
Task 2 Create airplane objects. 1. Create several instances of local class LCL_AIRPLANE and buffer their references into 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. Observe the execution of the program in the ABAP Debugger.
© Copyright . All rights reserved.
65
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. Template: SAPBC401_BAS_S1 Solution: SAPBC401_BAS_S2 Task 1 Define a reference variable. 1. Complete your ZBC401_##_MAIN program or copy the model solution from the previous exercise. 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.
Task 2 Create airplane objects. 1. Create several instances of local class LCL_AIRPLANE and buffer their references into 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. Observe the execution of the program in the ABAP Debugger. a) Carry out this step in the usual manner. For more information, refer to the SAP Library.
66
© Copyright . All rights reserved.
Lesson: Creating and Working with Objects
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.
67
Unit 2: Fundamental Object-Oriented Syntax
LESSON SUMMARY You should now be able to:
68
●
Create objects
●
Handle 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
Call Instance Methods
Figure 51: Calling Methods
© Copyright . All rights reserved.
69
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 shows the shorter syntax for method calls supported as of SAP NetWeaver AS 6.10in 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 NetWeaverAS 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.
70
© Copyright . All rights reserved.
Lesson: Accessing Methods and Attributes
Call of Static Methods
Figure 53: Calling Static Methods – Syntax
The RECEIVING, IMPORTING, and CHANGING parameters are mutually exclusive; otherwise, the same rules apply here as they do for calling a function module. Use CALLMETHOD 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.
71
Unit 2: Fundamental Object-Oriented Syntax
Call of Functional Methods
Figure 54: Functional Methods
Methods that have a RETURNING parameter are described as functional methods. Functional methods cannot have an EXPORTING or a CHANGING parameter. You must also pass a value to the RETURNING parameter using the VALUE addition. 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
●
Sources of values as a local copy: MOVE
●
72
Search clauses for internal tables, assuming that the operand is not a component of the table row: LOOP AT ... WHERE
© 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 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.
73
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.
74
© 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. Template: SAPBC401_BAS_S2 Solution: SAPBC401_BAS_S3 Task 1 Call the methods of your class. 1. Complete your ZBC401_##_MAIN program or copy the model solution from the previous exercise. 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.
Task 2 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.
© Copyright . All rights reserved.
75
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. Template: SAPBC401_BAS_S2 Solution: SAPBC401_BAS_S3 Task 1 Call the methods of your class. 1. Complete your ZBC401_##_MAIN program or copy the model solution from the previous exercise. 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. Caution: For reasons explained in the exercise Create UML Diagrams, you may 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.
Task 2 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.
76
© Copyright . All rights reserved.
Lesson: Accessing Methods and Attributes
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. a) See the source code extract from the model solution. 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. PROTECTED SECTION. 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. ENDMETHOD. "set_attributes
© Copyright . All rights reserved.
77
Unit 2: Fundamental Object-Oriented Syntax
METHOD
display_attributes.
DATA: lv_weight TYPE saplane-weight, lv_cap TYPE saplane-tankcap. 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.
78
© Copyright . All rights reserved.
Lesson: Accessing Methods and Attributes
* * * * * * * * * *
long syntax for functional call: CALL METHOD lcl_airplane=>get_n_o_airplanes RECEIVING rv_count = gv_count. a little bit shorter: 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.
79
Unit 2: Fundamental Object-Oriented Syntax
LESSON SUMMARY You should now be able to:
80
●
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 static constructors for the class in your ABAP Objects project. For this reason, you require the following knowledge: ●
An understanding of static constructors
●
An understanding of how to use static constructors
LESSON OBJECTIVES After completing this lesson, you will be able to: ●
Create and use constructors
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.
81
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 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: ● You must allocate resources
82
© 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.
83
Unit 2: Fundamental Object-Oriented Syntax
84
© 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. Template: SAPBC401_BAS_S3 Solution: SAPBC401_BAS_S4 Task 1 Define an instance constructor. 1. Complete your ZBC401_##_MAIN program or copy the model solution from the previous exercise, where ## is your two-digit group number. Define a constructor with a suitable signature for the instances of your class LCL_AIRPLANE. Implement the constructor in a way that the two instance attributes are set and instance counter N_O_AIRPLANES is increased by one. 2. Remove the definition and implementation of method SET_ATTRIBUTES to ensure that an attribute of instance can be set only once during its creation.
Task 2 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. Follow the execution of the program in the ABAP Debugger. Task 3 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 your class, define private instance attributes MV_WEIGHT (data type SAPLANE-WEIGHT) and MV_TANKCAP (data type SAPLANE_TANKCAP).
© Copyright . All rights reserved.
85
Unit 2: Fundamental Object-Oriented Syntax
2. Extend the definition of the instance constructor by adding a classical exception that is not class-based, WRONG_PLANETYPE. 3. 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. 4. Adjust the CREATE OBJECT statements so that you handle the exception. Only store the object reference in your table when the creation is successful. 5. 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.
86
© 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. Template: SAPBC401_BAS_S3 Solution: SAPBC401_BAS_S4 Task 1 Define an instance constructor. 1. Complete your ZBC401_##_MAIN program or copy the model solution from the previous exercise, where ## is your two-digit group number. Define a constructor with a suitable signature for the instances of your class LCL_AIRPLANE. Implement the constructor in a way that the two instance attributes are set and instance counter N_O_AIRPLANES is increased by one. a) See the source code extract from the model solution. 2. 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.
Task 2 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. Follow the execution of the program in the ABAP Debugger. a) Carry out this step in the usual manner. For more information about the ABAP Debugger, refer to the SAP Library. Task 3
© Copyright . All rights reserved.
87
Unit 2: Fundamental Object-Oriented Syntax
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 your class, 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. 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. 3. 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. 4. 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. 5. 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) Carry out this step in the usual manner. For more information about the ABAP Debugger, refer to the SAP Library. Solution - SAPBC401_BAS_S4 REPORT
sapbc401_bas_s4.
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: display_n_o_airplanes, get_n_o_airplanes RETURNING value(rv_count) TYPE i.
88
© Copyright . All rights reserved.
Lesson: Implementing Constructors in Local Classes
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) , / '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.
© Copyright . All rights reserved.
89
Unit 2: Fundamental Object-Oriented Syntax
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( ). ENDLOOP. gv_count = lcl_airplane=>get_n_o_airplanes( ). SKIP 2. WRITE: / 'Number of airplanes'(ca1), gv_count.
90
© Copyright . All rights reserved.
Lesson: Implementing Constructors in Local Classes
LESSON SUMMARY You should now be able to: ●
Create and use constructors
© Copyright . All rights reserved.
91
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 constructor
●
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
92
© Copyright . All rights reserved.
Lesson: Implementing Class Constructors in Local Classes
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 constructor signature does not have importing parameters or exceptions.
●
The static constructor must not 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 theme->as a prefix in such cases, but you can use it to improve readability. However, you must use theme->prefix when distinguishing between local data objects and instance attributes with the same name.
© Copyright . All rights reserved.
93
Unit 2: Fundamental Object-Oriented Syntax
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.
94
© 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, you read all the data just once in the static constructor and store it in a static attribute. Template: SAPBC401_BAS_S4 Solution: SAPBC401_BAS_S5 Task 1 Define an internal table as a private static attribute. Define a static constructor in which you fill the attribute with the complete content of database table SAPLANE. Use the ABAP Debugger to call the static constructor. 1. Complete your ZBC401_##_MAIN program or copy the model solution from the previous exercise. Define internal table GT_PLANETYPES as a private class attribute. To specify the type for the GT_PLANETYPES internal table, define private table typeTY_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. 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. 3. Use the ABAP Debugger to ensure that the static constructor is called correctly and that the internal table is filled in the main program. Where is the static constructor called in the main program? Task 2 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.
© Copyright . All rights reserved.
95
Unit 2: Fundamental Object-Oriented Syntax
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. The exception cannot be class-based. 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. Task 3 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 not? 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. Observe the execution of the program in the ABAP Debugger . 4. Which alternative solutions could be used to solve the tasks?
96
© 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, you read all the data just once in the static constructor and store it in a static attribute. Template: SAPBC401_BAS_S4 Solution: SAPBC401_BAS_S5 Task 1 Define an internal table as a private static attribute. Define a static constructor in which you fill the attribute with the complete content of database table SAPLANE. Use the ABAP Debugger to call the static constructor. 1. Complete your ZBC401_##_MAIN program or copy the model solution from the previous exercise. Define internal table GT_PLANETYPES as a private class attribute. To specify the type for the GT_PLANETYPES internal table, define private table typeTY_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. 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. 3. Use the ABAP Debugger to ensure that the static constructor is called correctly and that the internal table is filled in the main program. Where is the static constructor called in the main program? a) Before the class is accessed for the first time (before DISPLAY_N_O_AIRPLANES, in this case). Task 2 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.
97
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. The exception cannot be class-based. 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. Task 3 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 not? a) 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. Observe the execution of the program in the ABAP Debugger . a) Carry out this step in the usual manner. For more information on the ABAP Debugger, refer to the SAP Library. 4. Which alternative solutions could be used to solve the tasks? a) Define GET_TECHNCAL_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_PLANETYPE). In this case, the import parameter is not needed. b) Do not use a method to read GT_PLANETYPES.
98
© Copyright . All rights reserved.
Lesson: Implementing Class Constructors in Local Classes
In the instance constructor, you can access the class attribute GT_PLANETYPES directly (as 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 iv_type TYPE saplane-planetype EXPORTING ev_weight TYPE saplane-weight ev_tankcap TYPE saplane-tankcap
© Copyright . All rights reserved.
99
Unit 2: Fundamental Object-Oriented Syntax
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),
100
© 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
© Copyright . All rights reserved.
101
Unit 2: Fundamental Object-Oriented Syntax
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( ). ENDLOOP. gv_count = lcl_airplane=>get_n_o_airplanes( ). SKIP 2. WRITE: / 'Number of airplanes'(ca1), gv_count.
102
© 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.
103
Unit 2: Fundamental Object-Oriented Syntax
104
© Copyright . All rights reserved.
Unit 2 Learning Assessment
1. The CLASS statement can be nested, that is, you cannot 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 define the 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. The Garbage Collector is a system routine that starts automatically if the runtime system does not have important tasks to carry out. Determine whether this statement is true or false. X
True
X
False
© Copyright . All rights reserved.
105
Unit 2: Learning Assessment
5. Independent references are references that have been defined within a class. Determine whether this statement is true or false. X
True
X
False
6. You cannot create and address the objects using reference variables. Determine whether this statement is true or false. X
True
X
False
7. 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
8. Which of the following parameters are mutually exclusive? Choose the correct answers. X
A RECEIVING
X
B IMPORTING
X
C EXCEPTIONS
X
D CHANGING
9. When calling a static method from within the class, you can omit the class name. Determine whether this statement is true or false.
106
X
True
X
False
© Copyright . All rights reserved.
Unit 2: Learning Assessment
10. Which of the following expression(s) is used to call functional methods directly? Choose the correct answers. X
A ELSEIF
X
B COMPUTE
X
C MOVE
X
D WHILE
11. You can describe methods that have a _________ parameter as functional methods. Choose the correct answer. X
A EXPORTING
X
B CHANGING
X
C RETURNING
12. You have to pass the RETURNING parameter using the VALUE addition, that is, pass by value. Determine whether this statement is true or false. X
True
X
False
13. You can access static attributes using ____________. Choose the correct answer. X
A classname=>method_name
X
B classname=>static_attribute
X
C ref->instance_attribute
14. The _____________ is a special instance method in a class. Choose the correct answer. X
A constructor
X
B function
X
C attributes
© Copyright . All rights reserved.
107
Unit 2: Learning Assessment
15. The constructor is automatically called at runtime with the CREATE OBJECT statement. Determine whether this statement is true or false. X
True
X
False
16. Which of the following points do you consider when defining static constructors? 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 constructor’s signature can have importing parameters or exceptions.
X
D The static constructor must be called explicitly from the class.
17. The constructor’s signature can have importing parameters or exceptions. Determine whether this statement is true or false.
108
X
True
X
False
© Copyright . All rights reserved.
Unit 2 Learning Assessment - Answers
1. The CLASS statement can be nested, that is, you cannot 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 define the 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. The Garbage Collector is a system routine that starts automatically if the runtime system does not have important tasks to carry out. Determine whether this statement is true or false. X
True
X
False
© Copyright . All rights reserved.
109
Unit 2: Learning Assessment - Answers
5. Independent references are references that have been defined within a class. Determine whether this statement is true or false. X
True
X
False
6. You cannot create and address the objects using reference variables. Determine whether this statement is true or false. X
True
X
False
7. 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
8. Which of the following parameters are mutually exclusive? Choose the correct answers. X
A RECEIVING
X
B IMPORTING
X
C EXCEPTIONS
X
D CHANGING
9. When calling a static method from within the class, you can omit the class name. Determine whether this statement is true or false.
110
X
True
X
False
© Copyright . All rights reserved.
Unit 2: Learning Assessment - Answers
10. Which of the following expression(s) is used to call functional methods directly? Choose the correct answers. X
A ELSEIF
X
B COMPUTE
X
C MOVE
X
D WHILE
11. You can describe methods that have a _________ parameter as functional methods. Choose the correct answer. X
A EXPORTING
X
B CHANGING
X
C RETURNING
12. You have to pass the RETURNING parameter using the VALUE addition, that is, pass by value. Determine whether this statement is true or false. X
True
X
False
13. You can access static attributes using ____________. Choose the correct answer. X
A classname=>method_name
X
B classname=>static_attribute
X
C ref->instance_attribute
© Copyright . All rights reserved.
111
Unit 2: Learning Assessment - Answers
14. The _____________ is a special instance method in a class. Choose the correct answer. X
A constructor
X
B function
X
C attributes
15. The constructor is automatically called at runtime with the CREATE OBJECT statement. Determine whether this statement is true or false. X
True
X
False
16. Which of the following points do you consider when defining static constructors? 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 constructor’s signature can have importing parameters or exceptions.
X
D The static constructor must be called explicitly from the class.
17. The constructor’s signature can have importing parameters or exceptions. Determine whether this statement is true or false.
112
X
True
X
False
© Copyright . All rights reserved.
UNIT 3
Inheritance and Casting
Lesson 1 Implementing Inheritance Exercise 7: Implement Inheritance
114 123
Lesson 2 Implementing Up-Casts Using Inheritance Exercise 8: Implement Up-Casts
134 137
Lesson 3 Implementing Polymorphism Using Inheritance Exercise 9: Implement Polymorphism Using Inheritance
142 147
Lesson 4 Implementing Down-Casts Using Inheritance Exercise 10: Implement Down-Casts
154 157
UNIT OBJECTIVES ●
Explain generalization and specialization
●
Implement inheritance
●
Access elements of classes in inheritance
●
Implement up-casts using inheritance
●
Explain polymorphism
●
Implement polymorphism using inheritance
●
Implement down-casts using inheritance
●
Model class hierarchies
© Copyright . All rights reserved.
113
Unit 3 Lesson 1 Implementing Inheritance
LESSON OVERVIEW This lesson explains the concept of inheritance, its implementation and casting. 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
114
© 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 provides 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.
115
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. In other words, 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.
116
© 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 part 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 part 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.
117
Unit 3: Inheritance and Casting
Preserving Semantics During Redefinition
Figure 65: Preserving Semantics During Redefinition
In this example, the two redefined methods provide completely different information. The semantics of the method remains the same.
Definition of Subclass Constructors
Figure 66: Definition of the Constructor in Subclasses
A redefinition, as described for the above methods would not be useful in the case of the constructor. In the subclass, either the constructor of the superclass can be used without any
118
© Copyright . All rights reserved.
Lesson: Implementing Inheritance
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 refer to 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 reference of the superclass constructor, the subclass constructor 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 static constructor 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
If a subclass has not changed its instance constructor, the constructor is adopted from the superclass. The implementation is also inherited from the superclass.
© Copyright . All rights reserved.
119
Unit 3: Inheritance and Casting
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.
120
© 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 addressd 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 Summary of static components and inheritance are as follows: ●
●
●
●
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.
121
Unit 3: Inheritance and Casting
●
122
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. In this case, first access to the subclass is also the first access to the superclass.
© 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. Template SAPBC401_BAS_S5 Solution SAPBC401_INH_S1 Task 1 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. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) or copy the template program. 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 SFLIGHT-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 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.
Task 2 In the class LCL_AIRPLANE, define the local subclass LCL_CARGO_PLANE for cargo planes.
© Copyright . All rights reserved.
123
Unit 3: Inheritance and Casting
1. The class must have a private instance attribute, MV_CARGO, with the same type as the table field SCPLANE-CARGOMAX. 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.
Task 3 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. Call the static method DISPLAY_ATTRIBUTES second time.
Task 4 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.
124
© 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. Template SAPBC401_BAS_S5 Solution SAPBC401_INH_S1 Task 1 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. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) or copy the template program. 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 SFLIGHT-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 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.
© Copyright . All rights reserved.
125
Unit 3: Inheritance and Casting
a) See the source code extract from the model solution.
Task 2 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.
Task 3 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. Call the static method DISPLAY_ATTRIBUTES second time. a) See the source code extract from the model solution.
Task 4 Debug your program.
126
© Copyright . All rights reserved.
Lesson: Implementing Inheritance
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) Carry out this step in the usual manner. 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:
© Copyright . All rights reserved.
127
Unit 3: Inheritance and Casting
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. 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.
128
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
© Copyright . All rights reserved.
Lesson: Implementing Inheritance
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. 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 *------------------------------------------------*
© Copyright . All rights reserved.
129
Unit 3: Inheritance and Casting
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 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, 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(
130
© Copyright . All rights reserved.
Lesson: Implementing Inheritance
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 gv_count
TYPE TYPE TYPE TYPE TYPE
REF TO lcl_airplane, REF TO lcl_cargo_plane, REF TO lcl_passenger_plane, TABLE OF REF TO lcl_airplane, 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( ).
© Copyright . All rights reserved.
131
Unit 3: Inheritance and Casting
go_cargo->display_attributes( ). gv_count = lcl_airplane=>get_n_o_airplanes( ). SKIP 2. WRITE: / 'Number of airplanes'(ca1), gv_count.
132
© Copyright . All rights reserved.
Lesson: Implementing Inheritance
LESSON SUMMARY You should now be able to: ●
Explain generalization and specialization
●
Implement inheritance
●
Access elements of classes in inheritance
© Copyright . All rights reserved.
133
Unit 3 Lesson 2 Implementing Up-Casts 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 up-casts
LESSON OBJECTIVES After completing this lesson, you will be able to: ●
Implement up-casts using inheritance
The Up-Cast
Figure 70: Up-Cast (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
134
© Copyright . All rights reserved.
Lesson: Implementing Up-Casts Using Inheritance
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. 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:
© Copyright . All rights reserved.
135
Unit 3: Inheritance and Casting
object_id
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.
136
© Copyright . All rights reserved.
Unit 3 Exercise 8 Implement Up-Casts
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. Template SAPBC401_INH_S1 Solution SAPBC401_INH_S2 Task 1 Buffer the airplane references in a suitable type of internal table. 1. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) 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.
Task 2 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.
Task 3 Analyze your 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.
137
Unit 3 Solution 8 Implement Up-Casts
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. Template SAPBC401_INH_S1 Solution SAPBC401_INH_S2 Task 1 Buffer the airplane references in a suitable type of internal table. 1. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) 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.
Task 2 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.
Task 3 Analyze your program.
138
© Copyright . All rights reserved.
Lesson: Implementing Up-Casts Using Inheritance
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. 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 *-----------------------------------------------*
© Copyright . All rights reserved.
139
Unit 3: Inheritance and Casting
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( ). 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.
140
© Copyright . All rights reserved.
Lesson: Implementing Up-Casts Using Inheritance
LESSON SUMMARY You should now be able to: ●
Implement up-casts using inheritance
© Copyright . All rights reserved.
141
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
Figure 72: Generic Access After Up-Cast Assignments
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.
142
© Copyright . All rights reserved.
Lesson: Implementing Polymorphism Using Inheritance
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, ayou need to 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.
143
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.
Polymorphism
Figure 75: Polymorphism – Generic Access Using the Superclass Reference
144
© Copyright . All rights reserved.
Lesson: Implementing Polymorphism Using Inheritance
The implementation to be executed when DISPLAY_ATTRIBUTES is called will depend 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 very 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.
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
© Copyright . All rights reserved.
145
Unit 3: Inheritance and Casting
check whether the function model 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.
146
© 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. Template SAPBC401_INH_T3 Solution SAPBC401_INH_S3 Task 1 Define a local class for airlines. 1. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) or copy the template program. If you copy the template program then 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 store references 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 carrie itself is displayed but also all its airplanes. Use the previously defined DISPLAY_AIRPLANES_METHOD.
Task 2 In the main program, create an airline instance. Transfer some airplane references to the airline instance and display the attributes. 1. Remove all 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.
© Copyright . All rights reserved.
147
Unit 3: Inheritance and Casting
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.
148
© Copyright . All rights reserved.
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. Template SAPBC401_INH_T3 Solution SAPBC401_INH_S3 Task 1 Define a local class for airlines. 1. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) or copy the template program. If you copy the template program then 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 store references 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 carrie itself is displayed but also all its airplanes. Use the previously defined DISPLAY_AIRPLANES_METHOD. a) Refer the source code extract from the model solution.
Task 2
© Copyright . All rights reserved.
149
Unit 3: Inheritance and Casting
In the main program, create an airline instance. Transfer some airplane references to the airline instance and display the attributes. 1. Remove all 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. 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
150
© Copyright . All rights reserved.
Lesson: Implementing Polymorphism Using Inheritance
*------------------------------------------------* * 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. 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.
© Copyright . All rights reserved.
151
Unit 3: Inheritance and Casting
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. 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( ).
152
© Copyright . All rights reserved.
Lesson: Implementing Polymorphism Using Inheritance
LESSON SUMMARY You should now be able to: ●
Explain polymorphism
●
Implement polymorphism using inheritance
© Copyright . All rights reserved.
153
Unit 3 Lesson 4 Implementing Down-Casts Using Inheritance
LESSON OVERVIEW This lesson explains the concept of down-cast 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 down-casts
●
An understanding of inheritance
●
An understanding of implementing down-casts using Inheritance
LESSON OBJECTIVES After completing this lesson, you will be able to: ●
Implement down-casts using inheritance
●
Model class hierarchies
The Down-Cast
Figure 77: Down-Cast (Narrowing-Cast) with Object References
154
© Copyright . All rights reserved.
Lesson: Implementing Down-Casts Using Inheritance
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. To assign a superclass reference to a subclass reference, you must use the down-cast 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 class 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 given here, 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 Down-Cast Assignments
Figure 78: Specific Access After Down-Cast Assignments
Down-cast assignments is 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.
© Copyright . All rights reserved.
155
Unit 3: Inheritance and Casting
Exceptions Handling for Down-Casts
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 down-cast 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.
156
© Copyright . All rights reserved.
Unit 3 Exercise 10 Implement Down-Casts
Business Example As a developer, design an application where you want to know about the highest cargo load of all the cargo planes without knowing the details. Template: SAPBC401_INH_T3 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 down-cast technique to identify cargo planes. For those airplanes for which the down-cast 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.
157
Unit 3 Solution 10 Implement Down-Casts
Business Example As a developer, design an application where you want to know about the highest cargo load of all the cargo planes without knowing the details. Template: SAPBC401_INH_T3 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 down-cast technique to identify cargo planes. For those airplanes for which the down-cast 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.
158
© Copyright . All rights reserved.
Lesson: Implementing Down-Casts Using Inheritance
METHODS: constructor IMPORTING iv_name TYPE string iv_planetype TYPE saplane-planetype iv_cargo TYPE s_plan_car 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.
© Copyright . All rights reserved.
159
Unit 3: Inheritance and Casting
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, 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( ).
160
© Copyright . All rights reserved.
Lesson: Implementing Down-Casts Using Inheritance
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. *
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.
161
Unit 3: Inheritance and Casting
Correct Usage of Class Hierarchies
Figure 80: Usage of Class Hierarchies
As early as the modeling phase, you should be able to 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, the attribute should already have been defined in the superclass. There may be contradictions with reality when you try to implement a method for painting the cars.
162
© Copyright . All rights reserved.
Lesson: Implementing Down-Casts 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 needs 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 super class is also not appropriate.
© Copyright . All rights reserved.
163
Unit 3: Inheritance and Casting
LESSON SUMMARY You should now be able to:
164
●
Implement down-casts using inheritance
●
Model class hierarchies
© Copyright . All rights reserved.
Unit 3 Learning Assessment
1. Which of the following is a relationship in which the subclass inherits all the main characteristics of the superclass? Choose the correct answer. X
A Specialization
X
B Generalization
X
C Polymorphism
X
D Casting
2. Which of the following are the characteristics of generalization and specialization? 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
3. Which of the following can be called automatically in the superclass? Choose the correct answer. X
A Method
X
B Instance constructor
X
C Static constructor
X
D Object
© Copyright . All rights reserved.
165
Unit 3: Learning Assessment
4. A superclass is a generalization of its subclasses. Determine whether this statement is true or false. X
True
X
False
5. Which of the following section is used to change superclasses without the need to know the subclasses? Choose the correct answer. X
A PROTECTED
X
B PRIVATE
X
C PUBLIC
6. A __________ can always have a static constructor. Choose the correct answer. X
A subclass
X
B superclass
X
C subclass and superclass
7. Which of the following is used to define the static type of reference variable? Choose the correct answer.
166
X
A APPEND
X
B CREATE OBJECT
X
C TYPE REF TO
X
D CLASS
© Copyright . All rights reserved.
Unit 3: Learning Assessment
8. Which of the following is determined by the assignment? Choose the correct answer. X
A Superclass
X
B Static type
X
C Dynamic type
X
D Subclass
9. 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
10. 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
11. A typical use for ________ assignments is to prepare for generic access. Choose the correct answer. X
A events
X
B up-cast
X
C methods
X
D down-cast
© Copyright . All rights reserved.
167
Unit 3: Learning Assessment
12. 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
13. Which of the following is the down-cast assignment operator? Choose the correct answer. X
A APPEND
X
B CATCH
X
C MOVE ... ?TO ...
X
D TRY-ENDTRY
14. Suppose you have the same class X that inherits from class Y. After a down-cast, a reference variable that 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.
168
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
X
E Components inherited and redefined from a ‘Friend’ relationship
© Copyright . All rights reserved.
Unit 3: Learning Assessment
15. Suppose a reference variable that is typed on an interface contains an instance reference of a class that implements this interface and you copy this to a reference variable that is typed on 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
X
E Components from a ‘Friend’ relationship
16. 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 is a relationship in which the subclass inherits all the main characteristics of the superclass? Choose the correct answer. X
A Specialization
X
B Generalization
X
C Polymorphism
X
D Casting
2. Which of the following are the characteristics of generalization and specialization? 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
3. Which of the following can be called automatically in the superclass? Choose the correct answer.
170
X
A Method
X
B Instance constructor
X
C Static constructor
X
D Object
© Copyright . All rights reserved.
Unit 3: Learning Assessment - Answers
4. A superclass is a generalization of its subclasses. Determine whether this statement is true or false. X
True
X
False
5. Which of the following section is used to change superclasses without the need to know the subclasses? Choose the correct answer. X
A PROTECTED
X
B PRIVATE
X
C PUBLIC
6. A __________ can always have a static constructor. Choose the correct answer. X
A subclass
X
B superclass
X
C subclass and superclass
7. Which of the following is used to define the static type of reference variable? Choose the correct answer. X
A APPEND
X
B CREATE OBJECT
X
C TYPE REF TO
X
D CLASS
© Copyright . All rights reserved.
171
Unit 3: Learning Assessment - Answers
8. Which of the following is determined by the assignment? Choose the correct answer. X
A Superclass
X
B Static type
X
C Dynamic type
X
D Subclass
9. 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
10. When objects from different classes react differently to the same method calls, this is known as __________. Choose the correct answer.
172
X
A objects
X
B events
X
C polymorphism
X
D inheritance
© Copyright . All rights reserved.
Unit 3: Learning Assessment - Answers
11. A typical use for ________ assignments is to prepare for generic access. Choose the correct answer. X
A events
X
B up-cast
X
C methods
X
D down-cast
12. 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
13. Which of the following is the down-cast assignment operator? Choose the correct answer. X
A APPEND
X
B CATCH
X
C MOVE ... ?TO ...
X
D TRY-ENDTRY
© Copyright . All rights reserved.
173
Unit 3: Learning Assessment - Answers
14. Suppose you have the same class X that inherits from class Y. After a down-cast, a reference variable that 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
X
E Components inherited and redefined from a ‘Friend’ relationship
15. Suppose a reference variable that is typed on an interface contains an instance reference of a class that implements this interface and you copy this to a reference variable that is typed on 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
X
E Components from a ‘Friend’ relationship
16. What are the advantages of correctly using class hierarchies? Choose the correct answers.
174
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
176 181
Lesson 2 Implement Polymorphism Using Interfaces Exercise 12: Implement Polymorphism Using Interfaces
191 195
Lesson 3 Joining Classmodels Using Interfaces Exercise 13: Integrate Class Models Using Interfaces
202 205
UNIT OBJECTIVES ●
Explain the usage areas for interfaces
●
Create generalization and specialization relationships using interfaces
●
Implement polymorphism using interfaces
●
Implement down-casts with interfaces
●
Integrate different submodels using interfaces
●
Create and use interface hierarchies
© Copyright . All rights reserved.
175
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 usage areas for interfaces
●
Create generalization and specialization relationships using interfaces
Areas of Use for Interfaces
Figure 82: Central Definition of Shared Components
176
© Copyright . All rights reserved.
Lesson: Defining and Implementing Local Interfaces
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. Interfaces are 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.
Protocol Definition by Client
Figure 83: Client Defines The Protocoll
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.
177
Unit 4: Interfaces and Casting
Generic Access to Interface Components
Figure 84: Interfaces in UML Notation
In Unified Modeling Language (UML), you represent the interfaces in the same way as you represent classes. However, in addition to the interface’s 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.
Create Generalization and Specialization Relationships Using Interfaces
Figure 85: Defining and Implementing an Interface
178
© 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 To simplify access to interface components, you can use alias names. These alias names can appear in the definition part of a class or in the interface definition. The use of alias names is subject to the visibility restriction of the defining class. An alias for an interface method is 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.
Access to Interface Components
Figure 86: Addressing Interface Components Using Object References
© Copyright . All rights reserved.
179
Unit 4: Interfaces and Casting
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. Alternatively, you can use the alias names defined in the implementing class for the interface components. Even if shared components of the implementing classes are subsequently transferred to the interface, access to these components does not need to be adapted.
180
© 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. Define and implement the interface in your existing class for airlines. Template: SAPBC401_INH_S3 Solution: SAPBC401_INT_S1 Task 1 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 P-INCLUDE, and the START-OF-SELECTION event block to an E-INCLUDE. 1. Complete your program ZBC401_##_MAIN (## is your two-digit group number) 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 with ## being your two-digit group number). Create the INCLUDE through forward navigation. You can do this by double-clicking the INCLUDE’s name. 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.
181
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.
Task 2 Define an interface with the DISPLAY_PARTNER method in order to later offer generic access options to potential clients in the travel agency example. 1. Create a new INCLUDE (recommended name: ZBC401_##_AGENCY with ## being your twodigit group number) and define an interface LIF_PARTNER in the new INCLUDE. 2. 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. Check the entire program for syntactical correctness and activate it. Task 3 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.
Task 4 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.
182
© Copyright . All rights reserved.
Lesson: Defining and Implementing Local Interfaces
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. 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.
183
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. Define and implement the interface in your existing class for airlines. Template: SAPBC401_INH_S3 Solution: SAPBC401_INT_S1 Task 1 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 P-INCLUDE, and the START-OF-SELECTION event block to an E-INCLUDE. 1. Complete your program ZBC401_##_MAIN (## is your two-digit group number) 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 with ## being your two-digit group number). Create the INCLUDE through forward navigation. You can do this by double-clicking the INCLUDE’s name. a) See the source text excerpt from the model solution.
184
© Copyright . All rights reserved.
Lesson: Defining and Implementing Local Interfaces
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. 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.
Task 2 Define an interface with the DISPLAY_PARTNER method in order to later offer generic access options to potential clients in the travel agency example. 1. Create a new INCLUDE (recommended name: ZBC401_##_AGENCY with ## being your twodigit group number) and define an interface LIF_PARTNER in the new INCLUDE. a) See the source text excerpt from the model solution. 2. 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. Check the entire program for syntactical correctness and activate it. a) See the source text excerpt from the model solution. Task 3 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.
© Copyright . All rights reserved.
185
Unit 4: Interfaces and Casting
Task 4 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. 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 interface method’s call 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
186
© Copyright . All rights reserved.
Lesson: Defining and Implementing Local Interfaces
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) * 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 *----------------------------------------------------*
© Copyright . All rights reserved.
187
Unit 4: Interfaces and Casting
* 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: 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.
188
© Copyright . All rights reserved.
Lesson: Defining and Implementing Local Interfaces
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 METHOD lif_partner~display_partner. me->display_attributes( ). ENDMETHOD. "lif_partner~display_partner ENDCLASS.
"lcl_carrier IMPLEMENTATION
© Copyright . All rights reserved.
189
Unit 4: Interfaces and Casting
LESSON SUMMARY You should now be able to:
190
●
Explain the usage areas for interfaces
●
Create generalization and specialization relationships using interfaces
© Copyright . All rights reserved.
Unit 4 Lesson 2 Implement 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 87: Up-Cast 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 up-cast to copy a reference to the interface reference variable to perform polymorphism with interfaces.
© Copyright . All rights reserved.
191
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, atleast, remains unchanged. That is why you describe this type of assignment of reference variables as up-cast. 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 88: Row Type of the Internal Table in the Application Example
A typical area of use for up-cast 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. You 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.
192
© Copyright . All rights reserved.
Lesson: Implement Polymorphism Using Interfaces
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. 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. Polymorphism – Generic Access Using the Interface Reference
Figure 89: 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 go_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.
193
Unit 4: Interfaces and Casting
194
© 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. Template: SAPBC401_INH_T2 Solution: SAPBC401_INT_S2 Task 1 Define a local class for travel agencies. 1. Complete your program ZBC401_##_MAIN (## is your two-digit group number) 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.
Task 2
© Copyright . All rights reserved.
195
Unit 4: Interfaces and Casting
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. 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.
196
© 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. Template: SAPBC401_INH_T2 Solution: SAPBC401_INT_S2 Task 1 Define a local class for travel agencies. 1. Complete your program ZBC401_##_MAIN (## is your two-digit group number) or copy the template program with all its INCLUDES. a) Carry out this step in the usual manner. 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.
© Copyright . All rights reserved.
197
Unit 4: Interfaces and Casting
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.
Task 2 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.
198
© Copyright . All rights reserved.
Lesson: Implement Polymorphism Using Interfaces
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. 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
© Copyright . All rights reserved.
REF REF REF REF REF i.
TO TO TO TO TO
lcl_travel_agency, lcl_carrier, lcl_airplane, lcl_cargo_plane, lcl_passenger_plane,
199
Unit 4: Interfaces and Casting
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 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( ).
200
© Copyright . All rights reserved.
Lesson: Implement Polymorphism Using Interfaces
LESSON SUMMARY You should now be able to: ●
Implement polymorphism using interfaces
© Copyright . All rights reserved.
201
Unit 4 Lesson 3 Joining Classmodels 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:
202
●
Implement down-casts with interfaces
●
Integrate different submodels using interfaces
●
Create and use interface hierarchies
© Copyright . All rights reserved.
Lesson: Joining Classmodels Using Interfaces
Down-Casts with Interfaces
Figure 90: Down-Cast Assignment and Exception Handling in the Application Example
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 usually 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 here,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.
© Copyright . All rights reserved.
203
Unit 4: Interfaces and Casting
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 atruntime 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 down-cast. 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.
204
© 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. Template: SAPBC401_INT_T3 Solution: SAPBC401_INT_S3 Task 1 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. Complete your program ZBC401_##_MAIN (## is your two-digit group number) or copy the template program with all its INCLUDES. 2. If you have copied the template program, analyze it and continue with the next task. If you want to continue working with your own program then first copy INCLUDE program BC401_INT_T3_RENTAL (recommended name: ZBC401_##_RENTAL, where ## is your twodigit group number) and make the new INCLUDE program part of your own program. 3. In your main program, create an instance of LCL_RENTAL and a number of instances of vehicle classes. Add all 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.
Task 2 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.
© Copyright . All rights reserved.
205
Unit 4: Interfaces and Casting
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. Provide an implementation of the method defined in the interface. 5. Activate the INCLUDE with the definition and implementation of LCL_RENTAL. Then go to the main program and perform another syntax check Why does the call of ADD_PARTNER now work for the car rental company?
206
© 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. Template: SAPBC401_INT_T3 Solution: SAPBC401_INT_S3 Task 1 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. Complete your program ZBC401_##_MAIN (## is your two-digit group number) or copy the template program with all its INCLUDES. a) Carry out this step in the usual manner. For more information, refer to the SAP Library. 2. If you have copied the template program, analyze it and continue with the next task. If you want to continue working with your own program then first copy INCLUDE program BC401_INT_T3_RENTAL (recommended name: ZBC401_##_RENTAL, where ## is your twodigit group number) and make the new INCLUDE program part of your own program. a) Carry out this step in the usual manner. For more information, refer to the SAP Library. 3. In your main program, create an instance of LCL_RENTAL and a number of instances of vehicle classes. Add all 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.
Task 2 Implement interface LIF_PARTNER in class LCL_RENTAL.
© Copyright . All rights reserved.
207
Unit 4: Interfaces and Casting
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 up-cast 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, though, 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. Provide an implementation of the method defined in the interface. a) See the source text excerpt from the model solution. 5. Activate the INCLUDE with the definition and implementation of LCL_RENTAL. Then go to the main program and perform another syntax check a) 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: 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
208
© Copyright . All rights reserved.
Lesson: Joining Classmodels Using Interfaces
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. "lcl_truck DEFINITION *-------------------------------------------------* * 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 DEFINITION
© Copyright . All rights reserved.
209
Unit 4: Interfaces and Casting
*-------------------------------------------------* * 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. 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. "lcl_rental IMPLEMENTATION b) Solution - Main Program SAPBC401_INT_S3 REPORT sapbc401_int_s3. TYPE-POOLS icon. INCLUDE bc401_int_s3_agency. INCLUDE bc401_int_s3_carrier.
210
© Copyright . All rights reserved.
Lesson: Joining Classmodels Using Interfaces
INCLUDE bc401_int_s3_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. DATA: go_agency TYPE REF TO lcl_travel_agency, 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. 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
© Copyright . All rights reserved.
211
Unit 4: Interfaces and Casting
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( ). 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.
212
© Copyright . All rights reserved.
Lesson: Joining Classmodels Using Interfaces
Implementation of Interface Hierarchies
Figure 91: Interface Hierarchy in the Application Example
An interface implementation strongly resembles regular inheritance. You need to understand what the interface hierarchy looks like. You need to explain interface hierarchies using 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.
© Copyright . All rights reserved.
213
Unit 4: Interfaces and Casting
Compound Interface in Unified Modeling Language (UML) Notation
Figure 92: 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.
214
© Copyright . All rights reserved.
Lesson: Joining Classmodels Using Interfaces
Definition and Implementation of Compound Interfaces – Syntax
Figure 93: 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. The implementing class provides a central view of all components with their alias names.
© Copyright . All rights reserved.
215
Unit 4: Interfaces and Casting
Addressing Components in Compound Interfaces – Syntax
Figure 94: 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 95: 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.
216
© Copyright . All rights reserved.
Lesson: Joining Classmodels Using Interfaces
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.
© Copyright . All rights reserved.
217
Unit 4: Interfaces and Casting
LESSON SUMMARY You should now be able to:
218
●
Implement down-casts with interfaces
●
Integrate different submodels using interfaces
●
Create and use interface hierarchies
© Copyright . All rights reserved.
Unit 4 Learning Assessment
1. Which of the following technically differentiates interfaces from regular inheritance? Choose the correct answer. X
A Interfaces are superclasses that can be instantiated
X
B Interfaces do not have an implementation part
X
C Interfaces have only public components
2. Which of the following is defined in the interface? Choose the correct answer. X
A Services
X
B Methods
X
C Classes
3. Which of the following statements is used to implement an interface in a class? Choose the correct answer. X
A ALIASES
X
B METHODS
X
C INTERFACES
4. You can access interface components only by using an object reference. Determine whether this statement is true or false. X
True
X
False
© Copyright . All rights reserved.
219
Unit 4: Learning Assessment
5. Which of the following is used to search for the implementation of a method? Choose the correct answer. X
A The dynamic type reference variable
X
B The static type reference variable
X
C Method parameters
X
D A class
6. Which of the following is the main strength of interfaces? Choose the correct answer. X
A Events
X
B Inheritance
X
C Polymorphism
7. ?= is the down-cast assignment operator. Determine whether this statement is true or false. X
True
X
False
8. Which of the following implementation strongly resembles inheritance? Choose the correct answer. X
A Interface
X
B Class
X
C Method
9. Interfaces like regular superclasses 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. Which of the following technically differentiates interfaces from regular inheritance? Choose the correct answer. X
A Interfaces are superclasses that can be instantiated
X
B Interfaces do not have an implementation part
X
C Interfaces have only public components
2. Which of the following is defined in the interface? Choose the correct answer. X
A Services
X
B Methods
X
C Classes
3. Which of the following statements is used to implement an interface in a class? Choose the correct answer. X
A ALIASES
X
B METHODS
X
C INTERFACES
4. You can access interface components only by using an object reference. Determine whether this statement is true or false. X
True
X
False
© Copyright . All rights reserved.
221
Unit 4: Learning Assessment - Answers
5. Which of the following is used to search for the implementation of a method? Choose the correct answer. X
A The dynamic type reference variable
X
B The static type reference variable
X
C Method parameters
X
D A class
6. Which of the following is the main strength of interfaces? Choose the correct answer. X
A Events
X
B Inheritance
X
C Polymorphism
7. ?= is the down-cast assignment operator. Determine whether this statement is true or false. X
True
X
False
8. Which of the following implementation strongly resembles inheritance? Choose the correct answer. X
A Interface
X
B Class
X
C Method
9. Interfaces like regular superclasses 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 Event Handling for Interfaces
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 96: 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-OF-SELECTION, and so on. Also, do not confuse this concept with background processing or workflow control. Event Handling in a UML Class Diagram
Figure 97: 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». 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 an event in a class or instance. The syntax for this is RAISE EVENT eventname. 3. Define and implement the handler method in the Handler Class. The syntax for this is [CLASS -] METHODS … FOR EVENT …. OF. 4. Register handler objects or handler class to events at runtime. The syntax for this is SET HANDLER.
226
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Classes
Trigger and Handle Events
Figure 98: Defining and Triggering Events – Syntax
Depending on the status of your application, you may not need to program every step. The separation of cause and effect in your programming should 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. You can trigger static events only in static methods. 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 99: 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 eventtrigger 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).
228
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Classes
Event handler Registration
Figure 100: 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 instance(s) 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 101: 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 ...
230
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Classes
Event Handler Tables
Figure 102: 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. The following visibility sections determine where the events can be handled: PUBLIC
●
Can be accessed anywhere
© Copyright . All rights reserved.
231
Unit 5: Object-Oriented Events
●
PROTECTED Can only be handled within that class or its subclasses
●
PRIVATE Can only be handled within its class
Visibility of the handler method is as follows: PUBLIC
●
Anywhere in the program ●
PROTECTED Can be handled within that class or its subclasses
●
PRIVATE Can only be handled within its 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. Template: SAPBC401_INT_S3 Solution: SAPBC401_EVE_S1 Task 1 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 (## is your two-digit group number) 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.
© Copyright . All rights reserved.
233
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. 7. Where could the SET HANDLER statement be executed in the example given? Could this also be done from the main program?
8. Observe the execution of the program in the ABAP Debugger. 9. What would the syntax have to be in this case?
Task 2 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. Template: SAPBC401_INT_S3 Solution: SAPBC401_EVE_S1 Task 1 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 (## is your two-digit group number) 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.
© Copyright . All rights reserved.
235
Unit 5: Object-Oriented Events
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. 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. 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. 9. What would the syntax have to be in this case? SET HANDLER go_carrier->on_airplane_created FOR ALL INSTANCES. Task 2 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.
236
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Classes
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. 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
© Copyright . All rights reserved.
237
Unit 5: Object-Oriented Events
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. 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
238
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Classes
*-------------------------------------------* 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 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
© Copyright . All rights reserved.
239
Unit 5: Object-Oriented Events
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. 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.
240
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Classes
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 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
© Copyright . All rights reserved.
241
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. PUBLIC SECTION. INTERFACES: lif_partner. METHODS: constructor IMPORTING iv_name TYPE string, display_attributes. 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,
242
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Classes
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 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 go_carrier go_airplane go_cargo go_passenger gv_count
TYPE TYPE TYPE TYPE TYPE TYPE TYPE TYPE TYPE TYPE
REF REF REF REF REF REF REF REF REF i.
TO TO TO TO TO TO TO TO TO
lcl_vehicle, lcl_truck, lcl_bus, lcl_rental, 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 ).
© Copyright . All rights reserved.
243
Unit 5: Object-Oriented Events
******* 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. 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
Implement Event in a Local Interface Events can be defined as interface components. Triggering and handling events are done the same way as in classes. Steps to implement event handling for Interfaces are as follows: 1. Define events in interfaces 2. Trigger interface events in implementing classes 3. Handle interface events 4. Register event handling
246
© Copyright . All rights reserved.
Unit 5 Exercise 15 Implement Event Handling for Interfaces
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. 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 (where ## is your two-digit group number). 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 eventcontrolled. 3. If necessary, examine your UML diagram. Which class or interface should define the event? Which class or interface should trigger it? Which class or interface should handle 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 Event Handling for Interfaces
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. 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 (where ## is your two-digit group number). 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 eventcontrolled. a) See the source code extract from the model solution. 3. If necessary, examine your UML diagram. Which class or interface should define the event? Which class or interface should trigger it? Which class or interface should handle it? 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) Refer 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.
250
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Interfaces
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. 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
© Copyright . All rights reserved.
251
Unit 5: Object-Oriented Events
*--------------------------------------------------* * 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. ... 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 *-------------------------------------------------*
252
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Interfaces
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. ... 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
© Copyright . All rights reserved.
253
Unit 5: Object-Oriented Events
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.
"lcl_carrier IMPLEMENTATION
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
254
© Copyright . All rights reserved.
Lesson: Implementing Events in Local Interfaces
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 ). ***** 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 are not 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 define events within a class? Choose the correct answer. X
A CLASS-EVENTS
X
B RAISE EVENT
X
C EVENTS
X
D FOR EVENTS
3. 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
© Copyright . All rights reserved.
257
Unit 5: Learning Assessment
4. You can trigger static events only in static methods. Determine whether this statement is true or false. X
True
X
False
5. 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 event the reaction will trigger
X
C which instance(s) will perform the reaction
6. Events 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
7. Every object or class that has a defined event does not have a handler table. Determine whether this statement is true or false. X
True
X
False
8. Which of the following is used to handle the visibility of the event within the class or 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 are not 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 define events within a class? Choose the correct answer. X
A CLASS-EVENTS
X
B RAISE EVENT
X
C EVENTS
X
D FOR EVENTS
3. 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
© Copyright . All rights reserved.
259
Unit 5: Learning Assessment - Answers
4. You can trigger static events only in static methods. Determine whether this statement is true or false. X
True
X
False
5. 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 event the reaction will trigger
X
C which instance(s) will perform the reaction
6. Events 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
7. Every object or class that has a defined event does not have a handler table. Determine whether this statement is true or false. X
True
X
False
8. Which of the following is used to handle the visibility of the event within the class or 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
280 285
Lesson 3 Implementing Inheritance in Global Classes Exercise 18: Implement Inheritance in Global Classes
294 301
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
●
Handle global classes
●
Use the Refactoring Assistant
© Copyright . All rights reserved.
261
Unit 6 Lesson 1 Creating Global Classes
LESSON OVERVIEW This lesson explains the method of creating global classes. Business Example As a developer, you must create a global ABAP class for an airplane class 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 screenshots and screen illustrations 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, and so on. 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, that is the Class Builder. In case 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 103: 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 104: 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 105: 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 pushbutton 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 106: Definition of Method Signatures
In the method list, select a method and choose the Parameter pushbutton 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 Method or Next Methods pushbutton. Choose the Methods pushbutton to return to the method list. Implementation of Methods
Figure 107: 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 pushbutton to go to the source text maintenance if a method is already selected. You can implement the methods here.
Hint: Choose the relevant pushbutton to display the method’s signature.
Displaying the Method Definition
Figure 108: 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 109: 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 110: The Class Builder Testing Environment
You can test active active global classes by choosing menu path Class → Run → In Test Environment, click the corresponding 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 pushbutton. The system only lists the public components. Methods can be tested using the Execute Method icon. 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
Usage of Global Classes in the ABAP Editor
Figure 111: 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 112: Object Instantiation Using Drag and Drop
270
© Copyright . All rights reserved.
Lesson: Creating Global Classes
In the navigation area, select a class name and drag it to the editing area by holding down the left mouse pushbutton. This action creates a CREATE OBJECT statement. Then, add the reference variable and the actual parameters, if applicable, to the statement. Alternatively, you can also choose the Pattern pushbutton. You can find the CREATE OBJECT statement by selecting ABAP Objects Patterns. You can generate the statement using the input help. Your demonstration program will look similar to program SAPBC401_GCL_D1. It is recommended that you let the participants perform the first exercise of this lesson. Method Calls Using Drag and Drop
Figure 113: Method Calls Using Drag and Drop
In the navigation area, select a method name and drag it to the editing area by holding down the left mouse pushbutton. 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 pushbutton. The CALL METHOD statement is under ABAP Objects Pattern. You can generate the statement using the input help.
Note: To generate patterns, you can, as of SAP Netweaver 7.0, 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. Template: SAPBC401_EVE_S2 (main program) Solution: SAPBC401_GCL_S1 (main program) CL_HOTEL (global class) Task 1 Create a global class for hotels 1. Create the global class ZCL_##_HOTEL (## is your two-digit group number). 2. Define the following attributes in the class: Attribute Name
Type
Characteristics
C_POS_1
I
As a private constant with value 30.
MV_NAME
of the type STRING
As a private instance attribute.
MV_BEDS
of the type I
As a private instance attribute.
GV_N_O_HOTELS
of the type I
As a private static attribute.
Maintain the short texts. 3. Define the following methods in the class: Method Name
Method Characteristics
CONSTRUCTOR
Instance constructor for setting the private attributes with the import parameters IM_NAME and IM_BEDS
DISPLAY_ATTRIBUTES
Instance method for displaying attributes in an ABAP list
© Copyright . All rights reserved.
273
Unit 6: Object-Oriented Repository Objects
Method Name
Method Characteristics
DISPLAY_N_O_HOTELS
Static method to display the number of created hotel instances in an ABAP list
4. Use the constant defined before to align the output of the values in a column. Maintain the short texts.
Task 2 Check your work. 1. Activate your class. 2. Test your class in the Class Builder’s testing environment. Task 3 Create an instance of your global class for hotels in your main program. 1. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) or copy the template program. 2. Define a reference variable, specify your global hotel class as the type, and create an instance. 3. If you have not done the optional exercise, where you add business partners to the travel agency through event handling, call method ADD_PARTNER for the hotel. 4. Why can the hotel not yet be integrated into the list of travel agency of business partners?
5. 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. Template: SAPBC401_EVE_S2 (main program) Solution: SAPBC401_GCL_S1 (main program) CL_HOTEL (global class) Task 1 Create a global class for hotels 1. Create the global class ZCL_##_HOTEL (## is your two-digit group number). a) Follow the processes as outlined in the relevant section of this lesson. 2. Define the following attributes in the class: Attribute Name
Type
Characteristics
C_POS_1
I
As a private constant with value 30.
MV_NAME
of the type STRING
As a private instance attribute.
MV_BEDS
of the type I
As a private instance attribute.
GV_N_O_HOTELS
of the type I
As a private static attribute.
Maintain the short texts. a) Follow the processes as outlined in the relevant section of this lesson. 3. Define the following methods in the class: Method Name
Method Characteristics
CONSTRUCTOR
Instance constructor for setting the private attributes with the import parameters IM_NAME and IM_BEDS
© Copyright . All rights reserved.
275
Unit 6: Object-Oriented Repository Objects
Method Name
Method Characteristics
DISPLAY_ATTRIBUTES
Instance method for displaying attributes in an ABAP list
DISPLAY_N_O_HOTELS
Static method to display the number of created hotel instances in an ABAP list
4. Use the constant defined before to align the output of the values in a column. Maintain the short texts. a) Follow the processes as outlined in the relevant section of this lesson.
Task 2 Check your work. 1. Activate your class. a) Carry out this step in the usual manner. Additional information is available in the SAP Library. 2. Test your class in the Class Builder’s testing environment. a) Follow the processes as outlined in the relevant section of this lesson. Task 3 Create an instance of your global class for hotels in your main program. 1. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) or copy the template program. a) Carry out this step in the usual manner. For more information, refer to the SAP Library. 2. 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. 3. If you have not done the optional exercise, where you add business partners to the travel agency through event handling, call method ADD_PARTNER for the hotel. a) Perform in the same way as for the carrier and the car rental company. 4. Why can the hotel not yet be integrated into the list of travel agency of business partners? The global class for hotels does not implement the interface that is used by the travel agency class. 5.
276
© Copyright . All rights reserved.
Lesson: Creating Global Classes
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
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.
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
© Copyright . All rights reserved.
277
Unit 6: Object-Oriented Repository Objects
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. ***** 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( ).
278
© Copyright . All rights reserved.
Lesson: Creating Global Classes
LESSON SUMMARY You should now be able to: ●
Create global classes
●
Test global classes
●
Use global classes
© Copyright . All rights reserved.
279
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:
280
●
Define and implement global interfaces
●
Import local classes and interfaces
© Copyright . All rights reserved.
Lesson: Defining and Implementing Global Interfaces
Definition of Global Interfaces
Figure 114: Defining Global Interfaces
You create global interfaces like you create global classes. Right click in the Object Navigator. The naming convention is IF_ for SAP interfaces and ZIF_ or YIF_ for user-defined interfaces.
© Copyright . All rights reserved.
281
Unit 6: Object-Oriented Repository Objects
Implementation of Global Interfaces
Figure 115: 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 and 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.
282
© Copyright . All rights reserved.
Lesson: Defining and Implementing Global Interfaces
Import of Local Classes and Interfaces
Figure 116: 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 The steps to import local classes and interfaces are as follows: 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 Program dialog box, enter the name of the main program and, if the local classes and interfaces were defined within include programs, select Expand include checkbox. 4. Choose the Display Classes/Interfaces pushbutton. 5. Enter names for the global classes and interfaces that you want to create. 6. Remember the customer namespace, if applicable. 7. Choose the global classes and interfaces that you want to create and choose the Import pushbutton.
© Copyright . All rights reserved.
283
Unit 6: Object-Oriented Repository Objects
284
© 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. Template: SAPBC401_EVE_S2 (program) CL_HOTEL (global class) Solution: SAPBC401_GCL_S1 (program) CL_HOTEL2 (global class) IF_PARTNER (global interface) Task 1 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. (## is your two-digit group number). 2. Create the global interface ZIF_##_PARTNER. Define the instance method DISPLAY_PARTNER in your global interface. If the local interface contains the event PARTNER_CREATED, define the event in your global interface also. Hint: Instead of creating the global interface manually you can import the local interface from your program ZBC401_##_MAIN or the template program.
Task 2 Create a global interface for generalized access to business partner instances. Replace the local interface in your main program with the global interface. 1. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) or copy the template program. 2. Completely remove the definition of the local interface.
© Copyright . All rights reserved.
285
Unit 6: Object-Oriented Repository Objects
3. Adapt all places where the local interface was used so that the global interface is used and implemented instead. Hint: Use Find/Replace function of the ABAP Editor to reduce the typing efforts.
Task 3 Program your hotel class to implement the interface and test your program. 1. Complete your global class ZCL_##_HOTEL (where ## is your two-digit group number) or copy the template class. 2. In your main program, replace the reference to the template class with a reference to your own class. 3. 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. 4. Declare the interface as an implemented interface in your hotel class. 5. Implement the interface method in such a way that the hotel’s DISPLAY_ATTRIBUTES instance method is called. 6. Activate the global class and your program. Run your program. If you have done everything correctly, the hotel attributes now appear on the list. If the hotel attributes do not appear on the list, Otherwise, debug your program and analyze any errors that may have occurred.
286
© 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. Template: SAPBC401_EVE_S2 (program) CL_HOTEL (global class) Solution: SAPBC401_GCL_S1 (program) CL_HOTEL2 (global class) IF_PARTNER (global interface) Task 1 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. (## is your two-digit group number). a) Speak to your instructor if you have any questions. 2. Create the global interface ZIF_##_PARTNER. Define the instance method DISPLAY_PARTNER in your global interface. If the local interface contains the event PARTNER_CREATED, define the event in your global interface also. Hint: Instead of creating the global interface manually you can import the local interface from your program ZBC401_##_MAIN or the template program. a) Follow the processes as outlined in the relevant section of this lesson. Speak to your instructor if you have any questions. Task 2 Create a global interface for generalized access to business partner instances. Replace the local interface in your main program with the global interface. 1. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number) or copy the template program.
© Copyright . All rights reserved.
287
Unit 6: Object-Oriented Repository Objects
a) Carry out this step in the usual manner. For more information, refer to the SAP Library. 2. Completely remove the definition of the local interface. a) See source text excerpt from the model solution. 3. Adapt all places where the local interface was used so that the global interface is used and implemented instead. Hint: Use Find/Replace function of the ABAP Editor to reduce the typing efforts.
a) See source text excerpt from the model solution. Task 3 Program your hotel class to implement the interface and test your program. 1. Complete your global class ZCL_##_HOTEL (where ## is your two-digit group number) or copy the template class. a) Carry out this step in the usual manner. For more information, refer to the SAP Library. 2. In your main program, replace the reference to the template class with a reference to your own class. a) See source text excerpt from the model solution. 3. 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. 4. Declare the interface as an implemented interface in your hotel class. a) Follow the processes as outlined in the relevant section of this lesson. 5. Implement the interface method in such a way that the hotel’s DISPLAY_ATTRIBUTES instance method is called. a) Follow the processes as outlined in the relevant section of this lesson. 6. Activate the global class and your program. Run your program. If you have done everything correctly, the hotel attributes now appear on the list. If the hotel attributes do not appear on the list, Otherwise, debug your program and analyze any errors that may have occurred. a) Carry out this step in the usual manner. For more information, refer to the SAP Library. Include BC401_GCL_S2_AGENCY *------------------------------------------------* * INTERFACE lif_partners *------------------------------------------------* *INTERFACE lif_partner.
288
© Copyright . All rights reserved.
Lesson: Defining and Implementing Global Interfaces
* 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. METHOD
"display_agency_partners
constructor.
© Copyright . All rights reserved.
289
Unit 6: Object-Oriented Repository Objects
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 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
290
© Copyright . All rights reserved.
Lesson: Defining and Implementing Global Interfaces
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_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
© Copyright . All rights reserved.
291
Unit 6: Object-Oriented Repository Objects
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.
292
"lcl_rental IMPLEMENTATION
© 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.
293
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:
294
●
Generate UML diagrams for global classes
●
Implement inheritance in global classes
●
Handle global classes
●
Use the Refactoring Assistant
© Copyright . All rights reserved.
Lesson: Implementing Inheritance in Global Classes
Generation of UML Diagrams for Global Classes
Figure 117: Generate a UML Diagram for Package
As of SAP NetWeaver 7.0 Enhancement Package 2 (EhP2), the Class Builder can generate UML diagrams for existing coding. This function is restricted to global classes and does not apply to local classes. However, the diagrams can include objects from ABAP Dictionary. The figure shows how to start the functionality for a complete package. On a pop-up window, you can add a selection of objects and specify which details you want to see on the diagram.
© Copyright . All rights reserved.
295
Unit 6: Object-Oriented Repository Objects
Definition of Inheritance in Global Classes
Figure 118: Defining an Inheritance Relationship
Set out the inheritance relationships between global classes on the Properties tab page. Choose the Superclass pushbutton to specify a superclass. In the example shown in the figure, the subclass ZCL_CARGO_PLANE_00 inherits from superclass ZCL_AIRPLANE_00.
Redefinition of a Method in Global Class
Figure 119: Redefining an Inherited Method
296
© Copyright . All rights reserved.
Lesson: Implementing Inheritance in Global Classes
To redefine an inherited method, select the relevant method in the list and choose the Redefine pushbutton. Alternatively, you can use the context menu in the navigation area.
Note: The appearance of some of the icons or menus depends on the release level. The icon for redefining methods is one example.
Hint: To define the constructor in the subclass, choose the CONSTRUCTOR pushbutton 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.
Definition of Local Types in Global Classes
Figure 120: Defining a Local Type
You can define local types in global classes. Global classes includes 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. To edit the implementation parts of these local classes, choose the Impl pushbutton.
© Copyright . All rights reserved.
297
Unit 6: Object-Oriented Repository Objects
Display of Class Components
Figure 121: Structured Display of Inherited Components
To improve your understanding of inheritance and interface components, you can set the Group by Classes and Interfaces flag in the User-Specific Settings for 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 122: 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. .
298
© Copyright . All rights reserved.
Lesson: Implementing Inheritance in Global Classes
The Refactoring Assistant
Figure 123: Working with the Refactoring Assistant
Classes, interfaces and the associations between them are manifested by your ABAP implementation. Due to new business requirements you may wish to adapt and extend your ABAP implementation. Such adaptions are commonly called refactoring. The SAP Refactoring Assistant helps you to easily adapt the hierarchy and associations of classes and interfaces. For example, you can use the Refactoring Assistant to move the components of a class within the inheritance hierarchy. For a complete list of the features in this tool, refer to the SAP Library. Working with the tool is simple, because it is based on Drag and Drop dialogs.
Hint: The Tool Info pushbutton opens the SAP Library article about the Refactoring Assistant. There you can also find the descriptions about other abilities of the tool. Generally, the Refactoring Assistant does not adjust the implementation of methods. After using the Refactoring Assistant, you must check and adjust the method implementations manually. To Move a Method Definition from a Global Class to a Global Interface To move a method definition from a global class to a global interface, proceed as follows: 1. Change to the editing mode of a global class that implements a global interface. 2. Choose Tools → Refactoring Assistant. 3. In the tree structure that appears, open the folder for the method you want to move and the folder for target, which in this case, is implemented interface.
© Copyright . All rights reserved.
299
Unit 6: Object-Oriented Repository Objects
4. Move the method to the interface. 5. Choose Save. 6. If necessary, adapt statements calling the method in the source code. 7. Activate both the class and the interface.
300
© Copyright . All rights reserved.
Unit 6 Exercise 18 Implement Inheritance in Global Classes
Business Example Use inheritance and work with the Refactoring Assistant. Template: CL_HOTEL2 (global class) Solution: CL_HOTEL 3 (global class) CL_HOUSE (global class) Task 1 Define a global superclass for houses and have your hotel class inherit from it. 1. If necessary, add the class ZCL_##_HOUSE to your UML diagram. (## is your two-digit group number.) The class ZCL_##_HOUSE defines the attribute MV_NAME and the method DISPLAY_ATTRIBUTES. The class ZCL_##_HOTEL will inherit from the class ZCL_##_HOUSE. Draw the relationships in your UML diagram. 2. Create the global class ZCL_##_HOUSE and leave it empty. Caution: Make sure you deselect the final checkbox. The meaning of this property is explained in the next lesson. Speak to your instructor if you have any questions. 3. Define an inheritance relationship to make ZCL_##_HOUSE the superclass and ZCL_##_HOTEL the subclass. Speak to your instructor if you have any questions.
Task 2 Move the general components of the ZCL_##_HOTEL class to the superclass. 1. Use the Refactoring Assistant to move the c_POS_1 constant, the MV_NAME attribute, the instance constructor, and the DISPLAY_ATTRIBUTES method into the class ZCL_##_HOUSE. Speak to your instructor if you have any questions.
© Copyright . All rights reserved.
301
Unit 6: Object-Oriented Repository Objects
2. Adapt the signature and the implementation of the instance constructor in the superclass. Speak to your instructor if you have any questions. 3. Adapt the implementation of the DISPLAY_ATTRIBUTES method in the superclass. Speak to your instructor if you have any questions. 4. Define and implement the instance constructor for the superclass. Speak to your instructor if you have any questions. 5. Redefine the DISPLAY_ATTRIBUTES method in the subclass. Hint: To make constant C_POS_1 available in the implementation of DISPLAY_ATTRIBUTES of the subclass, you must change its visibility to protected. Speak to your instructor if you have any questions. 6. Observe the execution of the program in the ABAP Debugger.
302
© Copyright . All rights reserved.
Unit 6 Solution 18 Implement Inheritance in Global Classes
Business Example Use inheritance and work with the Refactoring Assistant. Template: CL_HOTEL2 (global class) Solution: CL_HOTEL 3 (global class) CL_HOUSE (global class) Task 1 Define a global superclass for houses and have your hotel class inherit from it. 1. If necessary, add the class ZCL_##_HOUSE to your UML diagram. (## is your two-digit group number.) The class ZCL_##_HOUSE defines the attribute MV_NAME and the method DISPLAY_ATTRIBUTES. The class ZCL_##_HOTEL will inherit from the class ZCL_##_HOUSE. Draw the relationships in your UML diagram. a) Speak to your instructor if you have any questions. 2. Create the global class ZCL_##_HOUSE and leave it empty. Caution: Make sure you deselect the final checkbox. The meaning of this property is explained in the next lesson. a) Follow the processes as outlined in the relevant section of this lesson. Speak to your instructor if you have any questions. 3. Define an inheritance relationship to make ZCL_##_HOUSE the superclass and ZCL_##_HOTEL the subclass. a) Follow the processes as outlined in the relevant section of this lesson. Speak to your instructor if you have any questions.
Task 2 Move the general components of the ZCL_##_HOTEL class to the superclass.
© Copyright . All rights reserved.
303
Unit 6: Object-Oriented Repository Objects
1. Use the Refactoring Assistant to move the c_POS_1 constant, the MV_NAME attribute, the instance constructor, and the DISPLAY_ATTRIBUTES method into the class ZCL_##_HOUSE. a) Follow the processes as outlined in the relevant section of this lesson. Speak to your instructor if you have any questions. 2. Adapt the signature and the implementation of the instance constructor in the superclass. a) Follow the processes as outlined in the relevant section of this lesson. Speak to your instructor if you have any questions. 3. Adapt the implementation of the DISPLAY_ATTRIBUTES method in the superclass. a) Follow the processes as outlined in the relevant section of this lesson. Speak to your instructor if you have any questions. 4. Define and implement the instance constructor for the superclass. a) Follow the processes as outlined in the relevant section of this lesson. Speak to your instructor if you have any questions. 5. Redefine the DISPLAY_ATTRIBUTES method in the subclass. Hint: To make constant C_POS_1 available in the implementation of DISPLAY_ATTRIBUTES of the subclass, you must change its visibility to protected. a) Follow the processes as outlined in the relevant section of this lesson. Speak to your instructor if you have any questions. 6. Observe the execution of the program in the ABAP Debugger. a) Carry out this step in the usual manner. For more information, refer to the SAP Library.
304
© Copyright . All rights reserved.
Lesson: Implementing Inheritance in Global Classes
LESSON SUMMARY You should now be able to: ●
Generate UML diagrams for global classes
●
Implement inheritance in global classes
●
Handle global classes
●
Use the Refactoring Assistant
© Copyright . All rights reserved.
305
Unit 6: Object-Oriented Repository Objects
306
© Copyright . All rights reserved.
Unit 6 Learning Assessment
1. You should use local classes or interfaces only within the program in which they are defined and implemented. Determine whether this statement is true or false. X
True
X
False
2. Which of the following are used to test the triggering of events in a class in the test environment? Choose the correct answers. X
A Select an event
X
B Choose Handler
X
C Call a method that triggers the event
3. You cannot convert to functional modern writing style when generating method calls in SAP NetWeaver (NW) Application Server (AS) 7.0. Determine whether this statement is true or false. X
True
X
False
4. The naming convention for SAP interfaces is ZIF_ or YIF_. Determine whether this statement is true or false. X
True
X
False
© Copyright . All rights reserved.
307
Unit 6: Learning Assessment
5. An interface object can be used to call a method from the implementing class of the interface. Determine whether this statement is true or false. X
True
X
False
6. Which of the following is used to generate UML diagrams for existing coding? Choose the correct answer. X
A Class Builder
X
B Superclass
X
C Methods
X
D Interfaces
7. Which of the following pushbutton is used to override an inherited method? Choose the correct answer. X
A CONSTRUCTOR
X
B Redefine
X
C Implementation
8. 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
9. You cannot use the Refactoring Assistant to move the components of a class within the inheritance hierarchy. Determine whether this statement is true or false.
308
X
True
X
False
© Copyright . All rights reserved.
Unit 6 Learning Assessment - Answers
1. You should use local classes or interfaces only within the program in which they are defined and implemented. Determine whether this statement is true or false. X
True
X
False
2. Which of the following are used to test the triggering of events in a class in the test environment? Choose the correct answers. X
A Select an event
X
B Choose Handler
X
C Call a method that triggers the event
3. You cannot convert to functional modern writing style when generating method calls in SAP NetWeaver (NW) Application Server (AS) 7.0. Determine whether this statement is true or false. X
True
X
False
4. The naming convention for SAP interfaces is ZIF_ or YIF_. Determine whether this statement is true or false. X
True
X
False
© Copyright . All rights reserved.
309
Unit 6: Learning Assessment - Answers
5. An interface object can be used to call a method from the implementing class of the interface. Determine whether this statement is true or false. X
True
X
False
6. Which of the following is used to generate UML diagrams for existing coding? Choose the correct answer. X
A Class Builder
X
B Superclass
X
C Methods
X
D Interfaces
7. Which of the following pushbutton is used to override an inherited method? Choose the correct answer. X
A CONSTRUCTOR
X
B Redefine
X
C Implementation
8. 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
9. You cannot use the Refactoring Assistant to move the components of a class within the inheritance hierarchy. Determine whether this statement is true or false.
310
X
True
X
False
© Copyright . All rights reserved.
UNIT 7
ABAP Object-Oriented Examples
Lesson 1 Implementing ABAP List Viewer (ALV) Exercise 19: Implement the ALV Grid Control Exercise 20: Implement a Popup with the ALV Grid Control
312 319 325
Lesson 2 Implementing Business Add-Ins (BAdIs)
334
UNIT OBJECTIVES ●
Implement simple ABAP List Viewer (ALV)
●
Implement double-click on ABAP List Viewer (ALV)
●
Describe Business Add-Ins (BAdIs)
© Copyright . All rights reserved.
311
Unit 7 Lesson 1 Implementing 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:
312
●
Implement simple ABAP List Viewer (ALV)
●
Implement double-click on ABAP List Viewer (ALV)
© Copyright . All rights reserved.
Lesson: Implementing ABAP List Viewer (ALV)
The ALV Grid Control
Figure 124: The ALV Grid Control
The 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, and so on. 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.
313
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,such as ALV Grid Control, Tree Control, Picture Control, and so on, are always embedded in this Container Control, which, in turn, is connected to the screen. There are different types of container controls. However, all incorporate fundamental control functions, such as scroll bars.
Usage of an ALV in a Screen Area
Figure 126: Displaying Application Data Using an ALV Grid Instance
314
© Copyright . All rights reserved.
Lesson: Implementing ABAP List Viewer (ALV)
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 then automatically creates the field catalog.
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.
Implementation of a Handler for the Double-Click Event
Figure 127: ALV Grid Control – Double-Click
© Copyright . All rights reserved.
315
Unit 7: ABAP Object-Oriented Examples
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, 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. 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.
316
© Copyright . All rights reserved.
Lesson: Implementing ABAP List Viewer (ALV)
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 Object Navigator also contains the Demo Center, which makes it very easy to use standard template programs. You can find the ABAP Workbench Object Navigator under Environment → Examples → Controls Examples. 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.
© Copyright . All rights reserved.
317
Unit 7: ABAP Object-Oriented Examples
318
© Copyright . All rights reserved.
Unit 7 Exercise 19 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. Template: SAPBC401_ALV_T1 Solution: SAPBC401_ALV_S1 Create an ALV Grid Control, and react to double-click on the ALV Grid Control. Task 1 Programming an ALV Grid Control and displaying 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.
Task 2 Handle a double-click on the ALV Grid Control.
© Copyright . All rights reserved.
319
Unit 7: ABAP Object-Oriented Examples
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. 2. Implement the handler method. Send a message of type I to output the row number and column name the user clicked. 3. Instantiate the handler class, and register the event handler method. 4. Activate and test your program.
320
© Copyright . All rights reserved.
Unit 7 Solution 19 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. Template: SAPBC401_ALV_T1 Solution: SAPBC401_ALV_S1 Create an ALV Grid Control, and react to double-click on the ALV Grid Control. Task 1 Programming an ALV Grid Control and displaying 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 in the usual manner. 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.
© Copyright . All rights reserved.
321
Unit 7: ABAP Object-Oriented Examples
Caution: You are working with a screen in this exercise, so always activate all parts of the program as well as the screen. a) Carry out this step in the usual manner.
Task 2 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, or refer to the corresponding slides on how to double-click the ALV Grid Control. 2. Implement the handler method. Send a message of type I to output the row number and column name the user clicked. a) You can use message 010 of message class BC401. 3. Instantiate the handler class, and register the event handler method. a) Review the source code extract from the model solution or refer to the corresponding slides on how to double-click the ALV Grid Control. 4. Activate and test your program. a) 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 *-------------------------------------------------* 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.
322
© Copyright . All rights reserved.
Lesson: Implementing ABAP List Viewer (ALV)
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 container_name = 'CONTAINER_1' EXCEPTIONS
© Copyright . All rights reserved.
323
Unit 7: ABAP Object-Oriented Examples
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.
324
" USER_COMMAND_0100
INPUT
© Copyright . All rights reserved.
Unit 7 Exercise 20 Implement a Popup 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. Template: SAPBC401_ALV_S1 Solution: SAPBC401_ALV_S2 Use advanced ALV Grid programming. Task 1 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 (where ## is your two-digit group number) 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 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.
325
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 MT_SFLIGHT is filled correctly.
Task 2 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. The CREATE OBJECT 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 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 the this procedure in detail.
326
© Copyright . All rights reserved.
Unit 7 Solution 20 Implement a Popup 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. Template: SAPBC401_ALV_S1 Solution: SAPBC401_ALV_S2 Use advanced ALV Grid programming. Task 1 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 (where ## is your two-digit group number) or copy the model solution from the previous exercise. a) Carry out this step in the usual manner. 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 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.
327
Unit 7: ABAP Object-Oriented Examples
Hint: Define a private table type TY_SFLIGHT in the same class.
a) Review 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) Review the source code extract from the model solution. 6. Activate your program and analyze it in the ABAP Debugger. Make sure MT_SFLIGHT is filled correctly. a) Carry out this step in the usual manner.
Task 2 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) Review 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. The CREATE OBJECT is not called repeatedly when the event handler method is executed repeatedly. a) Review 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 this method is only called if the dialog box container and the second ALV Grid Control have just been created. a) Review 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) Review the source code extract from the model solution.
328
© Copyright . All rights reserved.
Lesson: Implementing ABAP List Viewer (ALV)
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 the 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.
© Copyright . All rights reserved.
329
Unit 7: ABAP Object-Oriented Examples
READ TABLE gt_spfli INTO ls_spfli INDEX es_row_no-row_id. SELECT * FROM sflight INTO TABLE mt_sflight 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
330
© Copyright . All rights reserved.
Lesson: Implementing ABAP List Viewer (ALV)
*
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, 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.
© Copyright . All rights reserved.
331
Unit 7: ABAP Object-Oriented Examples
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 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.
332
" USER_COMMAND_0100
INPUT
© Copyright . All rights reserved.
Lesson: Implementing ABAP List Viewer (ALV)
LESSON SUMMARY You should now be able to: ●
Implement simple ABAP List Viewer (ALV)
●
Implement double-click on ABAP List Viewer (ALV)
© Copyright . All rights reserved.
333
Unit 7 Lesson 2 Implementing 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 BAdI
●
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 Business Add-Ins (BAdIs)
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.
334
© Copyright . All rights reserved.
Lesson: Implementing 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.
335
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_) with corresponding formally defined methods. The adapter class that is automatically generated during the interface definition (CL_EX_) has, among other capabilities, the function of calling all active implementations of the BAdI. When you have several active implementations, there isno 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. 2. As of SAP Netweaver 7.0 you cannot directly create a BAdI. First, you must create a so called Enhancement Spot. Within the Enhancement Spot definition, you can then create BAdI's on the Enhancement Spot Element Definitions tab strip. 3. Enter the definition name (). 4. Choose the Create pushbutton and enter the interface name () name in the corresponding dialog box.
336
© Copyright . All rights reserved.
Lesson: Implementing Business Add-Ins (BAdIs)
BAdI – The Calling Program
Figure 131: BAdI – The Calling Program
The figure 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.
Search for BAdIs You can search the BAdI using the following methods: ● 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).
●
●
●
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
© Copyright . All rights reserved.
337
Unit 7: ABAP Object-Oriented Examples
(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 the F1 key. On the appearing popup press the Technical Information pushbutton. 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. Remark: Don't use the editor's search function Edit → Find/Replace (Ctrl-F) because this function will consider a single source code include only.
Implement a BAdI
Figure 132: Implementation of a BAdI – SE19
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. 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 (the actual name of the implementation).
338
© Copyright . All rights reserved.
Lesson: Implementing Business Add-Ins (BAdIs)
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 or 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 Spot name) and choose the Create pushbutton. 3. Enter an implementation name and choose the OK pushbutton. 4. Enter a description text and choose the Save pushbutton. 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 Business Add-Ins (BAdIs)
© Copyright . All rights reserved.
339
Unit 7: ABAP Object-Oriented Examples
340
© 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 non-hierarchical lists in a standardized form. Determine whether this statement is true or false. X
True
X
False
2. Container controls do not provide the technical connection between the screen and 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.
341
Unit 7: Learning Assessment
5. With a Business Add-In (BAdI), an SAP application program provides the enhancement option through an interface. Determine whether this statement is true or false. X
True
X
False
6. An object of the 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 investigated. 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.
342
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 non-hierarchical lists in a standardized form. Determine whether this statement is true or false. X
True
X
False
2. Container controls do not provide the technical connection between the screen and 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.
343
Unit 7: Learning Assessment - Answers
5. With a Business Add-In (BAdI), an SAP application program provides the enhancement option through an interface. Determine whether this statement is true or false. X
True
X
False
6. An object of the 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 investigated. 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.
344
X
A method
X
B structure
X
C object
© Copyright . All rights reserved.
UNIT 8
Object-Oriented Design Patterns
Lesson 1 Implementing Special Object-Oriented Techniques
346
Lesson 2 Implementing the Singleton Pattern Exercise 21: Implement the Singleton Pattern
354 359
Lesson 3 Implementing Factory Classes Using Friendship Exercise 22: Implement a Factory Class Using Friendship
368 371
UNIT OBJECTIVES ●
Implement abstract classes
●
Implement final classes
●
Access internal tables with object references
●
Call navigation methods
●
Define the visibility of the instance constructor
●
Implement factory methods
●
Implement the singleton pattern
●
Implement friendship relationships
© Copyright . All rights reserved.
345
Unit 8 Lesson 1 Implementing Special 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:
346
●
Implement abstract classes
●
Implement final classes
●
Access internal tables with object references
●
Call navigation methods
●
Define the visibility of the instance constructor
© Copyright . All rights reserved.
Lesson: Implementing Special Object-Oriented Techniques
Abstract Classes
Figure 133: 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 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.
© Copyright . All rights reserved.
347
Unit 8: Object-Oriented Design Patterns
Final Classes
Figure 134: 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 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.
348
© Copyright . All rights reserved.
Lesson: Implementing Special Object-Oriented Techniques
Internal Tables with Object References
Figure 135: Read Access to a Table with Object References
Object references can be stored in internal tables. The example in the figure 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.
© Copyright . All rights reserved.
349
Unit 8: Object-Oriented Design Patterns
Read Access Using Public Attributes
Figure 136: Read Access Using Public Attributes
As shown in the figure, the key information redundancy can be avoided by making the key attributes public. Public attributes can be used directly to access internal tables in the READ TABLE and LOOP AT statement. The expression TABLE_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 lefthand side of WHERE clauses and WITH KEY additions. Therefore, public attributes are only used in some special cases in read-only mode.
350
© Copyright . All rights reserved.
Lesson: Implementing Special Object-Oriented Techniques
Call and Chain Navigation Methods
Figure 137: 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. Before the release of SAP NetWeaver 7.0 EhP2, it was mandatory to first store the reference to the new object in a reference variable. As of SAP NetWeaver 7.0 EhP2, we can chain method calls, that is, we can directly call a method of the object that the navigation method returns.
Hint: 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.
© Copyright . All rights reserved.
351
Unit 8: Object-Oriented Design Patterns
Visibility of the Instance Constructor
Figure 138: 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. Types of visibilities for the instance constructor, as follows: ● PRIVATE 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 “Factor-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-object-oriented 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 for the relevant class.
352
© Copyright . All rights reserved.
Lesson: Implementing Special Object-Oriented Techniques
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: ●
Implement abstract classes
●
Implement final classes
●
Access internal tables with object references
●
Call navigation methods
●
Define the visibility of the instance constructor
© Copyright . All rights reserved.
353
Unit 8 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 a instance of the class is created and has some advantages as compared to the instance constructor. Some advantages of factory methods are as follows: 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.
354
© Copyright . All rights reserved.
Lesson: Implementing the Singleton Pattern
●
Use factory methods to administrate the instances of a class within the class itself. 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 139: 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.
© Copyright . All rights reserved.
355
Unit 8: Object-Oriented Design Patterns
The Singleton Pattern
Figure 140: 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.
356
© Copyright . All rights reserved.
Lesson: Implementing the Singleton Pattern
Singleton Class - Using the Static Constructor
Figure 141: 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.
© Copyright . All rights reserved.
357
Unit 8: Object-Oriented Design Patterns
358
© Copyright . All rights reserved.
Unit 8 Exercise 21 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. Template: SAPBC401_GCL_S2 Solution: SAPBC401_SPC_S1 Task 1 Use the techniques of ABAP Objects to avoid the further specialization of passenger and cargo planes. 1. Complete your ZBC401_##_MAIN program or copy the template program. 2. Declare classes LCL_PASSENGER_PLANE and LCL_CARGO_PLANE as FINAL class. 3. What happens if you declare class LCL_AIRPLANE as FINAL class ?
4. What would happen if you make method DISPLAY_ATTRIBUTES in class LCL_AIRPLANE as final method?
Task 2 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. Task 3
© Copyright . All rights reserved.
359
Unit 8: Object-Oriented Design Patterns
Make sure 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. 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.
360
© Copyright . All rights reserved.
Unit 8 Solution 21 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. Template: SAPBC401_GCL_S2 Solution: SAPBC401_SPC_S1 Task 1 Use the techniques of ABAP Objects to avoid the further specialization of passenger and cargo planes. 1. Complete your ZBC401_##_MAIN program or copy the template program. a) Carry out this step in the usual manner. Additional information is available in the SAP Library. 2. Declare classes LCL_PASSENGER_PLANE and LCL_CARGO_PLANE as FINAL class. a) Refer the source code extract from the model solution. 3. What happens if you declare class LCL_AIRPLANE as FINAL class ? This results in a syntax error as classes LCL_CARGO_PLANE and LCL_PASSENGER_PLANE already inherited from this class. 4. What would happen if you make method DISPLAY_ATTRIBUTES in class LCL_AIRPLANE as final method? This results in a syntax error as the method is already redefined in classes LCL_CARGO_PLANE and LCL_PASSENGER_PLANE.
Task 2 Use the techniques of ABAP Objects to inhibit the instantiation of class LCL_AIRPLANE. 1. Declare LCL_AIRPLANE as an abstract class. a) Refer the source code extract from the model solution.
© Copyright . All rights reserved.
361
Unit 8: Object-Oriented Design Patterns
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 in the usual manner. Task 3 Make sure 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. Refer 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) Refer 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) Refer the source code extract from the model 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 *------------------------------------------------*
362
© Copyright . All rights reserved.
Lesson: Implementing the Singleton Pattern
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 *------------------------------------------------* * 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:
© Copyright . All rights reserved.
363
Unit 8: Object-Oriented Design Patterns
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'. 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.
364
© Copyright . All rights reserved.
Lesson: Implementing the Singleton Pattern
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'. 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 ********************************
© Copyright . All rights reserved.
365
Unit 8: Object-Oriented Design Patterns
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( ). * Optional part: Use method chain: * * lcl_travel_agency=>get_instance( )->display_attributes( ).
366
© 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.
367
Unit 8 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 classes for an airplane 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 142: Definition of a Friendship Relationship Between Classes
368
© 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 in the Class Builder. All classes and interfaces to which friendship is granted are listed there. Granting friendship is one direction. 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 143: 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_FACTORYserves 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.
369
Unit 8: 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, 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.
370
© Copyright . All rights reserved.
Unit 8 Exercise 22 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. Template: SAPBC401_SPC_S1 Solution: SAPBC401_ SPC_S2 Task 1 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. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number), or copy the template program. 2. Edit the include, which contains the classes for airplanes. Add the definition of the new class there. 3. 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 to do so.
4. Define a returning parameter (suggested name: RO_AIRPLANE). 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?
Task 2
© Copyright . All rights reserved.
371
Unit 8: Object-Oriented Design Patterns
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). Task 3 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.
Task 4 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.
372
© Copyright . All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
2. Do you have to actually receive the references to the new objects?
3. Activate, test, and debug your program.
© Copyright . All rights reserved.
373
Unit 8 Solution 22 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. Template: SAPBC401_SPC_S1 Solution: SAPBC401_ SPC_S2 Task 1 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. Complete your program ZBC401_##_MAIN (where ## is your two-digit group number), or copy the template program. a) Carry out this step in the usual manner. For more information, refer to the SAP Library. 2. 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. 3. 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 to do so.
a) Refer the source text excerpt from the model solution.
374
© Copyright . All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
4. Define a returning parameter (suggested name: RO_AIRPLANE). 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? a) You have to type the parameter with the common superclass of cargo planes and passenger planes, that is, TYPE REF TO lcl_airplane. Refer the source text excerpt from the model solution.
Task 2 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. Task 3 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.
© Copyright . All rights reserved.
375
Unit 8: Object-Oriented Design Patterns
a) Refer the source text excerpt from the model solution. Task 4 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. 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. Activate, test, and debug your program. a) Carry out this step in the usual manner. For more information, refer to the SAP Library. 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
376
© Copyright . All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
INHERITING FROM lcl_airplane FINAL CREATE PRIVATE FRIENDS lcl_airplane_factory. ... 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.
© Copyright . All rights reserved.
377
Unit 8: Object-Oriented Design Patterns
CLASS-METHODS: create_airplane IMPORTING iv_name TYPE string iv_planetype TYPE saplane-planetype iv_cargo TYPE s_plan_car OPTIONAL iv_seats TYPE s_seatsmax OPTIONAL RETURNING 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.
378
© Copyright . All rights reserved.
Lesson: Implementing Factory Classes Using Friendship
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. 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.
© Copyright . All rights reserved.
379
Unit 8: Object-Oriented Design Patterns
******* 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' 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( ).
380
© 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.
381
Unit 8: Object-Oriented Design Patterns
382
© Copyright . All rights reserved.
Unit 8 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 by using the final addition with the class statement. Determine whether this statement is true or false. X
True
X
False
3. By making the key attributes __________, we can avoid the redundant storage of information. Choose the correct answer. X
A public
X
B private
X
C protected
4. 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
© Copyright . All rights reserved.
383
Unit 8: Learning Assessment
5. If the instance constructor is protected, the visibility is extended to all of its subclasses. Determine whether this statement is true or false. X
True
X
False
6. Which of the following are the advantages of 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 implementation and signature.
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.
7. Which of the following is done using the singleton concept? Choose the correct answers. X
A Preventing a class from being instantiated more than once for the same program context
X
B Restricting the visibility of the instance constructor
X
C Keeping a reference to all its instances in a static attribute
X
D Storing only one instance instead of storing several instances
8. Which of the following concepts is used to provide a class access to the private components of the other class? Choose the correct answer.
384
X
A Singleton
X
B Friendship
X
C Interface
X
D Casting
© Copyright . All rights reserved.
Unit 8 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 by using the final addition with the class statement. Determine whether this statement is true or false. X
True
X
False
3. By making the key attributes __________, we can avoid the redundant storage of information. Choose the correct answer. X
A public
X
B private
X
C protected
4. 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
© Copyright . All rights reserved.
385
Unit 8: Learning Assessment - Answers
5. If the instance constructor is protected, the visibility is extended to all of its subclasses. Determine whether this statement is true or false. X
True
X
False
6. Which of the following are the advantages of 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 implementation and signature.
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.
7. Which of the following is done using the singleton concept? Choose the correct answers. X
A Preventing a class from being instantiated more than once for the same program context
X
B Restricting the visibility of the instance constructor
X
C Keeping a reference to all its instances in a static attribute
X
D Storing only one instance instead of storing several instances
8. Which of the following concepts is used to provide a class access to the private components of the other class? Choose the correct answer.
386
X
A Singleton
X
B Friendship
X
C Interface
X
D Casting
© Copyright . All rights reserved.
UNIT 9
Object-Oriented Exception Handling
Lesson 1 Explaining Class-Based Exception Handling
388
Lesson 2 Defining and Raising Exceptions Exercise 23: Implement Class-Based Exceptions
395 403
Lesson 3 Implementing Advanced Exception Handling Techniques Exercise 24: Map Exceptions to Each Other
418 427
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
●
Reraise exceptions
●
Map exceptions to each other
© Copyright . All rights reserved.
387
Unit 9 Lesson 1 Explaining Class-Based Exception Handling
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 Web AS 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.
388
© Copyright . All rights reserved.
Lesson: Explaining Class-Based Exception Handling
Figure 144: 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 normally means instantiating an exception class and setting the attributes. Handling a class-based exception involves evaluating the exception object and its attribute values. The program needs to raise and handle the exceptions. 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.
389
Unit 9: Object-Oriented Exception Handling
Hierarchy of Exception Classes
Figure 145: 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 usually 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 CX_. Those global exception classes that the runtime environment uses start with CX_SY_. SAP recommendeds 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. You must 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. The other groups must only be used 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 CX-ROOT.
390
© Copyright . All rights reserved.
Lesson: Explaining Class-Based Exception Handling
TRY-ENDTRY Control Structure
Figure 146: 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 TRYENDTRY 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 hander. If the TRY-ENDTRY block it does not find any exception class, the system gradually searches outwards in all 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 TRY-ENDTRY structure itself but instead in a surrounding TRY-ENDTRY structure or in a calling program.
© Copyright . All rights reserved.
391
Unit 9: Object-Oriented Exception Handling
Example Syntax for Handling Predefined Exceptions
Figure 147: Example Syntax for Handling Predefined Exceptions
The figure 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 handle 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 morespecific 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 documentation for each statement lists the classes whose exceptions may occur when that statement is executed.
392
© Copyright . All rights reserved.
Lesson: Explaining Class-Based Exception Handling
Analysis of Class-Based Exceptions in the Debugger
Figure 148: 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 pushbuttons appear if an exception occurrs. Use the pushbuttons to analyze the exception object and to navigate to the point in the source code where the exception occurred respectively.
Hint: For debugger runtime 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 Object pushbutton 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
© Copyright . All rights reserved.
393
Unit 9: Object-Oriented Exception Handling
●
394
Debug class-based exceptions
© Copyright . All rights reserved.
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 Object 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: ●
Define global exception classes
●
Raise class-based exceptions
●
Propagate exceptions
© Copyright . All rights reserved.
395
Unit 9: Object-Oriented Exception Handling
Definition of Global Exception Classes
Figure 149: 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 NW AS 6.40), you can still select the with Message Class checkbox when you create an exception class. You take the texts that should appear when exceptions occur from the messages classes identified in the message statement. You find these known messages and message classes in table T100. In releases before SAP NW 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).
396
© Copyright . All rights reserved.
Lesson: Defining and Raising 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 150: 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 &&.
Note: For the first text you create, always use a predefined static constant as an ID. The text always has the same name as the exception class itself. If you have not specified 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.
© Copyright . All rights reserved.
397
Unit 9: Object-Oriented Exception Handling
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 run time. 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.
Raising of Class-Based Exceptions
Figure 151: Variants of Statement RAISE EXCEPTION
The figure shows an example for each variants of 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 [EXPORTING ...]. This statement creates a new exception object that is an instance of the class. RAISE EXCEPTION . This statement uses an existing exception object that the one points to. The exception object was either created directly using a CREATE OBJECT statement or caught in a previous CATCH ... INTO ...statement.
398
© 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.
Set Exception Text
Figure 152: 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, 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, and so on.
© Copyright . All rights reserved.
399
Unit 9: Object-Oriented Exception Handling
Exception Propagation
Figure 153: Propagating Class-Based Exceptions
You do not necessarily need to handle exceptions that occur in procedures where they occur. You can instead propagate exceptions to the caller of the procedure. The caller can then handle the exception or propagate it to its own caller, and so on. The highest levels to which an exception can be propagated are processing blocks without local data areas, that is, event blocks or dialog modules. You must deal with the exceptions propagated by the called procedures while you deal with any exceptions raised within the processing block itself. Otherwise, a runtime error occurs. 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_.... In RAISING statement, list 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, form, or function module can raise only one type of exception, that is, either class-based or conventional.
400
© Copyright . All rights reserved.
Lesson: Defining and Raising Exceptions
Propagating Exceptions Over Several Hierarchy – Levels
Figure 154: 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 excpetion, 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 is executed before the CATCH block of the main program.
© Copyright . All rights reserved.
401
Unit 9: Object-Oriented Exception Handling
402
© Copyright . All rights reserved.
Unit 9 Exercise 23 Implement Class-Based Exceptions
Business Example Your program should use the class-based exception concept if an invalid plane type is provided when creating an airplane instance. Template: SAPBC401_GCL_S2 Solution: SAPBC401_EXC_S1 (Main program) CX_INVALID_PLANETYPE (exception class) Task 1 Create a global exception class for an invalid airplane type. 1. Create a global exception class called ZCX_##_INVALID_PLANETYPE (where ## is your twodigit group number). Set 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. Hint: To state whether or not the messages from a message class are used when you create the exception class,select the Message Class checkbox. 2. Add an attribute for the airplane type (suggested name: PLANETYPE) and assign the type S_PLANETYPE to it. Make sure 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.
403
Unit 9: Object-Oriented Exception Handling
Hint: You can define your own message class and message or use message 020 from message class BC401.
Task 2 Raise the new exception in method GET_TECHNICAL ATTRIBUTES of your local class LCL_AIRPLANE. 1. Complete program ZBC401_##_MAIN or copy the template program. 2. 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. 3. Edit the implementation of method GET_TECHNICAL_ATTRIBUTES and raise the class-based 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. Task 3 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 GET_TECHNICAL_ATTRIBUTES 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 classbased exception WRONG_PLANETYPE from the signature of the CONSTRUCTOR method and replace it with your new class-based exception ZCX_##_INVALID_PLANETYPE. 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. 5. Repeat the previous steps with local class LCL_CARGO_PLANE.
404
© Copyright . All rights reserved.
Lesson: Defining and Raising Exceptions
Task 4 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. 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. Activate and test your program. For test purposes, create an airplane with a wrong plane type and debug the propagation of the exception.
© Copyright . All rights reserved.
405
Unit 9 Solution 23 Implement Class-Based Exceptions
Business Example Your program should use the class-based exception concept if an invalid plane type is provided when creating an airplane instance. Template: SAPBC401_GCL_S2 Solution: SAPBC401_EXC_S1 (Main program) CX_INVALID_PLANETYPE (exception class) Task 1 Create a global exception class for an invalid airplane type. 1. Create a global exception class called ZCX_##_INVALID_PLANETYPE (where ## is your twodigit group number). Set 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. Hint: To state whether or not the messages from a message class are used when you create the exception class,select the Message Class checkbox. a) Create a global class. b) On the following window, choose the CX_STATIC_CHECK superclass. c) Choose the Exception Class option and select the Message Class checkbox. 2. Add an attribute for the airplane type (suggested name: PLANETYPE) and assign the type S_PLANETYPE to it. Make sure a corresponding parameter is defined in the signature of the constructor.
406
© Copyright . All rights reserved.
Lesson: Defining and Raising Exceptions
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) Go to the Attributes tab. 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) Go to the Texts tab. 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.
Task 2 Raise the new exception in method GET_TECHNICAL ATTRIBUTES of your local class LCL_AIRPLANE. 1. Complete program ZBC401_##_MAIN or copy the template program. a) Carry out this step as usual. Additional information is available in SAP Library. 2. 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. 3. Edit the implementation of method GET_TECHNICAL_ATTRIBUTES and raise the class-based 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. Task 3 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 GET_TECHNICAL_ATTRIBUTES and replace it with your new class-based exception, ZCX_##_INVALID_PLANETYPE.
© Copyright . All rights reserved.
407
Unit 9: Object-Oriented Exception Handling
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. 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 classbased exception WRONG_PLANETYPE from the signature of the CONSTRUCTOR method and replace it with your new class-based exception ZCX_##_INVALID_PLANETYPE. 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. 5. Repeat the previous steps with local class LCL_CARGO_PLANE. a) See the source code extract from the model solution. Task 4 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).
408
© Copyright . All rights reserved.
Lesson: Defining and Raising Exceptions
a) See the source code extract from the model solution. 5. Activate and test your program. For test purposes, create an airplane with a wrong plane type and debug the propagation of the exception. a) Perform this step in the usual manner. 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
© Copyright . All rights reserved.
409
Unit 9: Object-Oriented Exception Handling
* *
IMPORTING iv_type TYPE saplane-planetype EXPORTING ev_weight TYPE saplane-weight ev_tankcap TYPE saplane-tankcap EXCEPTIONS wrong_planetype. 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) , AT c_pos_1 mv_name, / 'Type of Airplane:'(002), AT c_pos_1 mv_planetype, / 'Weight:'(003), AT c_pos_1 mv_weight LEFT-JUSTIFIED,
410
© Copyright . All rights reserved.
Lesson: Defining and Raising Exceptions
/ '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_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.
© Copyright . All rights reserved.
411
Unit 9: Object-Oriented Exception Handling
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
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.
412
"lcl_passenger_plane DEFINITION
© Copyright . All rights reserved.
Lesson: Defining and Raising Exceptions
*-----------------------------------------------* * 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 *---------------------------------------------------* * 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.
© Copyright . All rights reserved.
413
Unit 9: Object-Oriented Exception Handling
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'. ******* 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'.
414
© Copyright . All rights reserved.
Lesson: Defining and Raising Exceptions
***** 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. * * * * * * * * * * * *
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 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'.
© Copyright . All rights reserved.
415
Unit 9: Object-Oriented Exception Handling
*
ENDIF.
******* show attributes of all partners of travel_agency go_agency->display_attributes( ).
416
© Copyright . All rights reserved.
Lesson: Defining and Raising Exceptions
LESSON SUMMARY You should now be able to: ●
Define global exception classes
●
Raise class-based exceptions
●
Propagate exceptions
© Copyright . All rights reserved.
417
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:
418
●
Explain the hierarchy of predefined exception classes
●
Explain different ways of handling an exception
●
Retry after exceptions
●
Implement resumable exceptions
●
Reraise exceptions
●
Map exceptions to each other
© Copyright . All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
The Hierarchy of Predefined Exception Classes
Figure 155: Integration of Standard Exceptions in the Runtime System
The figure illustrates the consequences that may arise as you choose the superclass of an exception class. It also 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 class is not handled 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.
© Copyright . All rights reserved.
419
Unit 9: Object-Oriented Exception Handling
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 handlethese 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.
Different Ways of Handling an Exception After an exception was caught in a CATCH statement, you can handle it without stopping the program. Use the following techniques to handle an exception caught in a CATCH statement without stopping the program: 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 that is new as of SAP NW 7.0 EhP 2. From where the exception occurred (using statement RESUME that is new as of SAP NW 7.0 EhP 2).
3. Raise and propagate one of the following exceptions:
420
●
The same exception object again using RAISE EXCEPTION .
●
A new exception using RAISE EXCEPTION TYPE .
© Copyright . All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
Implementation of Retry After Exceptions
Figure 156: RETRY statement
When you handle an exception in a CATCH block, use the RETRYstatement 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.
© Copyright . All rights reserved.
421
Unit 9: Object-Oriented Exception Handling
Implementation of Resumable Exceptions
Figure 157: RETRY statement
Hint: This technique is new with Release SAP NW 7.0 EhP 2.
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 in which the exception was raised 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.
422
© Copyright . All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
Hint: Respective checkboxes are available in Class Builder and Function Builder when defining the signature of a method or the interface of a function module. 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
Figure 158: 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. If you do not add the BEFORE UNWIND addition, the system deletes the newly created instance before executing the CATCH block. You will not be able to resume the GET_TECH_ATTR method and the constructor would not be executed.
© Copyright . All rights reserved.
423
Unit 9: Object-Oriented Exception Handling
Implementation of Re-Raise Exceptions
Figure 159: Reraising an Existing Exception Object
You re-raise class-based exceptions with one of the following variants of statement RAISE EXCEPTION: ●
RAISE EXCEPTION TYPE [EXPORTING ...] This statement creates a new exception object, which is an instance of class . Optionally, values can be provided for the constructor using the EXPORTING addition.
●
RAISE EXCEPTION This statement uses an existing exception object, namely whichever exception object points to. This exception object iseither 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.
424
© Copyright . All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
Mapping of Exceptions to Each Other
Figure 160: 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 it leaves the CATCH block. Therefore, the handler on the top level can only access the last exceptionobject. However,you can chain exception objects, that is, you can let one exceptionobject point to the one before, which points to the one before it, and so on. The handler of an exception follows the chain and evaluates each exception object in the sequence. All exception classes provide a public instance attribute PREVIOUS.You type the attributewith REF TO CX_ROOTto 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.
© Copyright . All rights reserved.
425
Unit 9: Object-Oriented Exception Handling
426
© Copyright . All rights reserved.
Unit 9 Exercise 24 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. Template: SAPBC401_EXC_S1 Solution: SAPBC401_EXC_S2 Task 1 In the constructor of local class LCL_AIRPLANE, handle the exception raised by method GET_TECHNICAL_ATTRIBUTES. 1. Complete program ZBC401_##_MAIN or copy the template program. 2. Edit the implementation of the constructor of local class LCL_AIRPLANE. Define a local object reference (suggested name: LX_INV_PLANETYPE) and enter it so that it points to the exception object raised by method GET_TECHNICAL_ATTRIBUTES. 3. Implement a TRY-ENDTRY structure for exception handling. Catch the exception object, but leave the CATCH block empty for now.
Task 2 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, map the new exception with the original one raised by get_technical_attributes so that the constructor handles both 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.
© Copyright . All rights reserved.
427
Unit 9: Object-Oriented Exception Handling
2. Adjust the signature of the constructor so that it propagates the new exception. 3. Which other method signatures do you have to adjust to propagate the exception up to the main program?
Task 3 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 everytime 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 export the text of the original exception. Output the text on the list.
428
© Copyright . All rights reserved.
Unit 9 Solution 24 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. Template: SAPBC401_EXC_S1 Solution: SAPBC401_EXC_S2 Task 1 In the constructor of local class LCL_AIRPLANE, handle the exception raised by method GET_TECHNICAL_ATTRIBUTES. 1. Complete program ZBC401_##_MAIN or copy the template program. a) Carry out this step as usual. For more information, refer to the SAP Library. 2. Edit the implementation of the constructor of local class LCL_AIRPLANE. Define a local object reference (suggested name: LX_INV_PLANETYPE) and enter it so that it points to the exception object raised by method GET_TECHNICAL_ATTRIBUTES. a) Refer the source code extract from the model solution. 3. Implement a TRY-ENDTRY structure for exception handling. Catch the exception object, but leave the CATCH block empty for now. a) Refer the source code extract from the model solution.
Task 2 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, map the new exception with the original one raised by get_technical_attributes so that the constructor handles both exceptions.
© Copyright . All rights reserved.
429
Unit 9: Object-Oriented Exception Handling
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) Refer the source code extract from the model solution. 2. Adjust the signature of the constructor so that it propagates the new exception. a) Refer the source code extract from the model solution. 3. 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. Task 3 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 everytime 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) Refer 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) Refer the source code extract from the model solution. 3. Use the same variables to export the text of the original exception. Output the text on the list. a) Refer the source code extract from the model solution. Include BC401_EXC_S2_CARRIER *---------------------------------------------------* * CLASS lcl_airplane DEFINITION *---------------------------------------------------* CLASS lcl_airplane DEFINITION. PUBLIC SECTION.
*
430
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.
© Copyright . All rights reserved.
431
Unit 9: Object-Oriented Exception Handling
TRY.
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.
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
432
© Copyright . All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
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_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.
© Copyright . All rights reserved.
433
Unit 9: Object-Oriented Exception Handling
PRIVATE SECTION. DATA: mv_seats TYPE s_seatsmax. 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 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.
434
© Copyright . All rights reserved.
Lesson: Implementing Advanced Exception Handling Techniques
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. ******* 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( ).
© Copyright . All rights reserved.
435
Unit 9: Object-Oriented Exception Handling
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. 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( ).
436
© 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
●
Reraise exceptions
●
Map exceptions to each other
© Copyright . All rights reserved.
437
Unit 9: Object-Oriented Exception Handling
438
© Copyright . All rights reserved.
Unit 9 Learning Assessment
1. Which of the following statement 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 block 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. An 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.
439
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 options can be selected when you create an exception class? Choose the correct answer. X
A The exception class radio button
X
B The with Message Class checkbox
X
C The usual ABAP Class radio button
8. Which of the following is the step to define global exception classes? Choose the correct answer.
440
X
A Create a global class with the class type as exception class.
X
B Define additional attributes.
X
C Save as exception texts.
X
D Activate the exception class.
© Copyright . All rights reserved.
Unit 9: Learning Assessment
9. Which of the following syntax addition 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
10. Which of the following blocks of code is executed before the CATCH block of the main program after an exception has occurred? Choose the correct answers. X
A CLEANUP
X
B TRY
X
C CATCH
X
D RESUME
11. 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
12. Which of the following is/are the way(s) to handle exception besides stopping the program? 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
© Copyright . All rights reserved.
441
Unit 9: Learning Assessment
13. 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
14. Which of the following is a prerequisite for using the RESUME statement? Choose the correct answers. X
A The exception has to be caught.
X
B The exception has to marked resumable.
X
C The exception has to be propagated.
X
D The exception has to be raised.
15. Which of the following statements raise a new exception object? Choose the correct answers.
442
X
A RAISE
X
B RESUME
X
C CATCH
© Copyright . All rights reserved.
Unit 9 Learning Assessment - Answers
1. Which of the following statement 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 block 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. An 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
© Copyright . All rights reserved.
443
Unit 9: Learning Assessment - Answers
4. TRY-ENDTRY structures can be nested to any depth. Determine whether this statement is true or false. X
True
X
False
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 options can be selected when you create an exception class? Choose the correct answer.
444
X
A The exception class radio button
X
B The with Message Class checkbox
X
C The usual ABAP Class radio button
© Copyright . All rights reserved.
Unit 9: Learning Assessment - Answers
8. Which of the following is the step to define global exception classes? Choose the correct answer. X
A Create a global class with the class type as exception class.
X
B Define additional attributes.
X
C Save as exception texts.
X
D Activate the exception class.
9. Which of the following syntax addition 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
10. Which of the following blocks of code is executed before the CATCH block of the main program after an exception has occurred? Choose the correct answers. X
A CLEANUP
X
B TRY
X
C CATCH
X
D RESUME
11. 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.
445
Unit 9: Learning Assessment - Answers
12. Which of the following is/are the way(s) to handle exception besides stopping the program? 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
13. 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
14. Which of the following is a prerequisite for using the RESUME statement? Choose the correct answers. X
A The exception has to be caught.
X
B The exception has to marked resumable.
X
C The exception has to be propagated.
X
D The exception has to be raised.
15. Which of the following statements raise a new exception object? Choose the correct answers.
446
X
A RAISE
X
B RESUME
X
C CATCH
© Copyright . All rights reserved.
UNIT 10
Program Calls and Memory Management
Lesson 1 Using Shared Objects Exercise 25: Use Shared Objects
448 467
UNIT OBJECTIVES ●
Explain shared objects
●
Use shared objects
© Copyright . All rights reserved.
447
Unit 10 Lesson 1 Using Shared Objects
LESSON OVERVIEW This lesson explains how you can save data as shared objects in shared memory, and examine this concept and its implementation. Business Example You want to develop a transaction in which many users can access the same data concurrently without having to read it from the database each time. You know that shared objects can be used to make data in the main memory accessible across session boundaries. Accordingly, you must familiarize yourself with this technique. For this reason, you require the following knowledge: ●
An understanding of how classes are created for shared objects
●
An understanding of how you can use shared objects to implement applications
●
An understanding of access shared objects from within an ABAP program
LESSON OBJECTIVES After completing this lesson, you will be able to: ●
Explain shared objects
●
Use shared objects
Motivation As of SAP NetWeaver 2004, you can save data as shared objects in shared memory, across different programs and even different user sessions. Accordingly, you can create applications in which users write data to this area. Other users can then read this data later. The potential uses for shared objects are as follows: ●
Saving a catalog An “author” writes the catalog to the shared objects area. Many users can then access this catalog at the same time.
●
Saving a shopping cart The buyer fills the shopping cart and the seller reads the filled shopping cart later.
448
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Shared Memory
Figure 161: Memory Model of an Application Server
Shared memory is a memory area on an application server that the ABAP programs running on the same server can access. Before SAP introduced shared objects, ABAP statements had to use the EXPORT and IMPORT statements with the SHARED BUFFER and SHARED MEMORY additions to access this memory area. Instances of classes were active exclusively in the internal session of an ABAP program. With the introduction of shared objects in SAP NetWeaver 2004, shared memory has been enhanced with Shared Objects Memory, where the user can save shared objects. You can save shared objects in areas of shared memory.
Note: Instances of classes can be saved. It is not yet possible to save any data objects as shared objects. However, you can save data objects apart from reference variables as attributes of classes.
© Copyright . All rights reserved.
449
Unit 10: Program Calls and Memory Management
Access Shared Objects
Figure 162: Accessing Shared Objects
The figure above explains how a shared object is being viewed by two user sessions simultaneously.
Shared Objects The following are important points about shared objects: ●
Cross-program buffering of data that is read often, but rarely written.
●
Concurrent read accesses are supported by shared objects.
●
Access is controlled by a lock mechanism.
●
Data is saved as attributes of objects.
●
Memory bottlenecks result in runtime errors and you need to identify them.
The write accesses should not be frequent because writing data to the shared objects area is performance intensive. Specifically, you want to optimize runtime, which would be lost if write access were more frequent.
450
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Note: SAP also uses shared objects in SAP NetWeaver 2004. For example, this technique is used to navigate in the ABAP Workbench. In addition to saving memory which is around 3 MB per user logon, navigation during the first access is faster by up to a factor of 100. A prerequisite for saving an object in shared memory is that you need to define the class of the object with the SHARED MEMORY ENABLED addition of the CLASS statement. Also, you can select the SHARED MEMORY ENABLED attribute in the CLASS BUILDER.
Areas and Area Instances
Figure 163: Areas and Area Instances
An area is the template for area instances in shared memory. One area can generate several area instances, which differ by name. In addition, an area instance can have several versions which differ in their version IDs or version numbers. In the simplest case, without version management, an area instance consists of a single area instance version.
© Copyright . All rights reserved.
451
Unit 10: Program Calls and Memory Management
Area Classes and Area Handles
Figure 164: Creating an Area
You define an area in transaction SHMA. This creates a global, final area class of the same name. This is a subclass of CL_SHM_AREA. In an ABAP program, you can access the area exclusively using methods of the generated area class.
Hint: As the area and area class have the same name, it is advised to name the area according to the naming conventions for classes - ZCL_*, for example, in the customer namespace. You can use static methods (Attach methods) of an area class to attach an ABAP program, or its internal session where the system processes the ABAP program, to an area instance in shared memory. When you attach an ABAP program, an instance of the area class is created as an area handle. The figure also illustrates another class, which is the area root class. You can create any number of objects in an area instance, depending on your specific program. You access these objects uniformly through the instance of the area root class.
Note: You limit yourselves to two classes in a specific example.
452
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Example Application
Figure 165: Example Application
In this lesson, you develop a simple catalog application as an example. You want to use shared objects to create a catalog of flight dates, where the users can select any flight quickly. Access Areas
Figure 166: Accessing Areas
© Copyright . All rights reserved.
453
Unit 10: Program Calls and Memory Management
The figure highlights the fact that any programs can access objects in the shared objects memory. In this case, two applications, which run in different user sessions, access objects in the same area. For the example application, the requirements are as follows: Creating an area
●
●
Developing a program to create an area instance
●
Developing a program to read data from the area
Shared Memory Area – Definition
Figure 167: Area Management
You save shared objects in areas of shared memory. You use transaction SHMA to create and manage areas and their attributes.
Hint: Note that you have to call transaction code SHMA directly in SAP NetWeaver 2004, because it has not been added to the menu tree yet. Call transaction code SHMA and enter the name of the area. The usual namespace rules apply, which means the area name has to start with Y or Z in the customer system. The system also supports namespaces containing slashes.
Hint: Note that, for this area, the system generates an identically named global and final area class as a subclass of CL_SHM_AREA. Therefore, it is advised to choose the area name wisely, as shown in the example. In an ABAP program, an area is accessed exclusively using methods of the generated area class.
454
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Maintenance of Areas
Figure 168: Maintaining Areas
After you choose one of the pushbuttons Create, Change or Display, the system displays the maintenance screen for areas. The system has linked each area with a global area root class, whose attributes can contain proprietary data and references to other shared memory-enabled classes. You have to assign the area root class to an area when you maintain it. If an area instance version is not empty, it has to contain at least an instance of the area root class as its root object, which the system uses to reference other objects. When you generate the area class, the system generates and types a ROOT attribute with the static type of the area root class. Important terms for creating an area are as follows: ● Client-dependent area Areas, and thus the objects within an area, do not have a client ID by default. You can however specify an area as client-dependent. In client-dependent areas, the methods of the area class for accessing an area instance refer to the active client by default. You can use the optional importing parameter CLIENT to access another client explicitly. ●
Transactional area An area instance version of a transactional area is not active immediately after you remove a change lock with the DETACH_COMMIT method. It is not active until the next database commit. This is particularly helpful in implementing shopping carts in the shared objects memory.
© Copyright . All rights reserved.
455
Unit 10: Program Calls and Memory Management
Shared Memory Area – Write Access
Figure 169: Before Creating an Area Instance
You have defined an area. You have also created the classes that will be instantiated. Now, you examine the statements that can be used to create an area instance. You continue to use the previous example. When you create an area, the system creates a global final class with the same name. To set up an area or access an existing area, you need a reference variable that you can type with the generated area class. This reference serves as a handle for accessing the area.
456
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Area Instance Creation
Figure 170: Area Instance Creation
When you instantiate the area class, the system creates an instance of the area in shared memory. The program has a handle for this instance of the area. It performs all future operations using this handle. Object Generation in Shared Memory
Figure 171: Object Generation in Shared Memory
© Copyright . All rights reserved.
457
Unit 10: Program Calls and Memory Management
Once you create the area instance, you can create the objects in the shared objects memory. To do so, use the AREA HANDLE addition for the CREATE OBJECT statement. This statement informs the system about the area instance where it should create the objects. Object Generation in Shared Memory II
Figure 172: Object Generation in Shared Memory II
The figure illustrates how you can instantiate both objects from within the program. Alternatively, you can instantiate the root object from within the program. You can create the other objects in this area instance from the constructor of the root without assigning references (in this case).
458
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Root Object Setting
Figure 173: Root Object Setting
To be able to address the objects that you create in the area instance, assign the root object to the ROOT attribute of the area handle. To do so, use the SET_ROOT method of the area handle. As a consequence, any program of any application can access this area. To do so, the application merely has to fetch a reference to the area instance, and can then immediately access the objects contained in that area instance.
© Copyright . All rights reserved.
459
Unit 10: Program Calls and Memory Management
Write Lock Releasing
Figure 174: Write Lock Releasing
Read access of an area instance is not possible until the release of write lock. For the read access, use the DETACH_COMMIT method, which inherits the area class from class CL_SHM_AREA.
Shared Memory Area – Read Access
Figure 175: Accessing an Existing Object in Shared Memory
460
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Once an area instance has been set up, other users and applications can access it. The reading programs have to implement the following steps: 1. The read program first needs a reference variable that is you type with the area class. This reference variable serves as a handle for the area instance access. 2. The program obtains the handle for the area instance using method ATTACH_FOR_READ, which class CL_SHM_AREA provides. This sets a read lock that prevents the system to erase the area instance during the access. 3. The objects in this area instance are now accessible by always using the area handle. Read Lock Cancellation
Figure 176: Read Lock Cancellation
Once the read activity is complete, the application releases the read lock using the method DETACH of the area handle. The application automatically releases the read lock when the internal session is closed after a DETACH statement.
© Copyright . All rights reserved.
461
Unit 10: Program Calls and Memory Management
Shared Memory Area – Versioning
Figure 177: Setting a Read Lock on the Active Version
When you create an area, you can specify that the system allows several versions of an area instance. To determine what exactly these area instance versions mean, you need to examine an example. A normal state is when an area instance has been set up. Once the setup is complete using method DETACH_COMMIT, and the system sends a database commit, the area instance version is active.
462
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Version Being Set Up
Figure 178: Version Being Set Up
If the NUMBER OF VERSIONS attribute of the area is set appropriately, additional versions of the area instance can exist in addition to the active version. When a new catalog is being set up, several temporary versions of the same area instance exist concurrently. As soon as an application sets a change lock for an area instance, a “version being set up” is created and exists in parallel to the active version.
© Copyright . All rights reserved.
463
Unit 10: Program Calls and Memory Management
Write Complete – Previous Version is Outdated
Figure 179: Write Complete – Previous Version is Outdated
If you complete the setup of the new version during a read access of the currently active version, the version being set up becomes active. The previously active version is given the attribute OUTDATED. New Read Locks for the New Active Version
Figure 180: New Read Locks for the New Active Version
464
© Copyright . All rights reserved.
Lesson: Using Shared Objects
The read locks for the outdated version remain until the read operations are complete. In contrast, new read locks for the area instance are always set for the active version. Therefore, two different readers can produce two different read results in this case. No More Read Blocks for Outdated Version – Version Expired
Figure 181: No More Read Blocks for Outdated Version – Version Expired
When you remove the last existing read lock from outdated version, the outdated version expires. The garbage collector then deletes the expired version. You cannot set any read locks for versions that expire, or use them to determine the number of versions. This is important if the system restricts the number of area instance versions.
© Copyright . All rights reserved.
465
Unit 10: Program Calls and Memory Management
New Read Locks for Active Version
Figure 182: New Read Locks for Active Version
New read locks are always set for the active version. There can only be one active version for each area instance. Depending on the maximum number of versions, several outdated versions for which read locks are still set can exist in parallel to the new version.
466
© Copyright . All rights reserved.
Unit 10 Exercise 25 Use Shared Objects
Business Example You want to run an Internet shop based on an SAP system. To give your Internet customers the fastest possible access to your catalog, you save it in the shared objects memory. Write program to manage and describe the catalog and develop a test application to read the data. Template None Solution CL_BC402_SHS_ROOT (global class) CL_BC402_SHS_CATALOG (global class) BC402_SHS_WRITE_CATALOG (executable program) BC402_SHS_READ_CATALOG (executable program) Create a shared objects area, write and read data on this area. Task 1 Create an area in shared objects memory (suggested name: ZCL_BC402_##_AREA, where ## is your group number). 1. Use transaction SHMA to create an area in shared memory. This area should have the following attributes: ●
Client-specific Area
●
With Versioning
●
Displacement not Possible
The system automatically prompts you to specify a root class. Create an area root class (suggested name: ZCL_BC402_##_ROOT). 2. Implement the area root class. It should merely contain a reference to the catalog class that you will create in the next exercise task. Task 2 Create a global class where the catalog data is to be saved (suggested name: CL_BC402_##_CATALOG). This class requires a method for writing the catalog data and another method for retrieving the data. It also requires a global attribute and an internal table that saves the catalog data.
© Copyright . All rights reserved.
467
Unit 10: Program Calls and Memory Management
1. Create the global class for the catalog data. Note that this class has to be shared memoryenabled. 2. Create a private instance attribute in the class (suggested name: MT_CATALOG). Enter it with a table type that has structure SDYN_CONN as a line type. 3. Create a public instance method to fill the catalog (suggested name: FILL_CATALOG). This method requires an importing parameter that will be given the internal table with data. Implement the method. 4. Create a second public instance method that can be used to answer flight date queries (suggested name: GET_FLIGHTS). This method requires one importing parameter each for the departure and destination cities, as well as two additional parameters for the different flight dates. The method also needs an exporting parameter that returns the matching flights. Implement the method. Task 3 Create an executable program that builds the area in shared objects memory (suggested name: ZBC402_##_WRITE_CATALOG). This program is also supposed to read the catalog data from the database and pass it on to the appropriate class. 1. Create an executable program. 2. Define three reference variables, one each for the area handle, the area root class, and the catalog class. 3. Create an area, an instance of the catalog class, and an instance of the area root class. Set up the area. Read the necessary catalog data from tables SPFLI and SFLIGHT. 4. Don’t forget to delete the write lock after the data is written successfully. 5. Execute the program and then use the Shared Objects Monitor to examine the shared memory area. Task 4 Implement a read program to read data from the area you just created (suggested name: ZBC402_##_READ_CATALOG). Output the data in a simple user dialog (using the provided function module BC402_DISPLAY_TABLE, for example). 1. Create an executable program. 2. Define a selection screen in which the user can enter the departure and destination cities. The user should also be able to enter an earliest and latest possible flight date. 3. Make sure the data is read from the catalog object. Output the data in the user dialog.
468
© Copyright . All rights reserved.
Unit 10 Solution 25 Use Shared Objects
Business Example You want to run an Internet shop based on an SAP system. To give your Internet customers the fastest possible access to your catalog, you save it in the shared objects memory. Write program to manage and describe the catalog and develop a test application to read the data. Template None Solution CL_BC402_SHS_ROOT (global class) CL_BC402_SHS_CATALOG (global class) BC402_SHS_WRITE_CATALOG (executable program) BC402_SHS_READ_CATALOG (executable program) Create a shared objects area, write and read data on this area. Task 1 Create an area in shared objects memory (suggested name: ZCL_BC402_##_AREA, where ## is your group number). 1. Use transaction SHMA to create an area in shared memory. This area should have the following attributes: ●
Client-specific Area
●
With Versioning
●
Displacement not Possible
The system automatically prompts you to specify a root class. Create an area root class (suggested name: ZCL_BC402_##_ROOT). a) Follow the instructor’s demonstration. 2. Implement the area root class. It should merely contain a reference to the catalog class that you will create in the next exercise task. a) See the source code excerpt from the model solution. Task 2 Create a global class where the catalog data is to be saved (suggested name: CL_BC402_##_CATALOG). This class requires a method for writing the catalog data and another
© Copyright . All rights reserved.
469
Unit 10: Program Calls and Memory Management
method for retrieving the data. It also requires a global attribute and an internal table that saves the catalog data. 1. Create the global class for the catalog data. Note that this class has to be shared memoryenabled. a) Create the class in the CLASS BUILDER. Use the sample solution as a guide. 2. Create a private instance attribute in the class (suggested name: MT_CATALOG). Enter it with a table type that has structure SDYN_CONN as a line type. a) See the source code excerpt from the model solution. 3. Create a public instance method to fill the catalog (suggested name: FILL_CATALOG). This method requires an importing parameter that will be given the internal table with data. Implement the method. a) See the source code excerpt from the model solution. 4. Create a second public instance method that can be used to answer flight date queries (suggested name: GET_FLIGHTS). This method requires one importing parameter each for the departure and destination cities, as well as two additional parameters for the different flight dates. The method also needs an exporting parameter that returns the matching flights. Implement the method. a) See the source code excerpt from the model solution. Task 3 Create an executable program that builds the area in shared objects memory (suggested name: ZBC402_##_WRITE_CATALOG). This program is also supposed to read the catalog data from the database and pass it on to the appropriate class. 1. Create an executable program. a) Carry out this step in the usual manner. 2. Define three reference variables, one each for the area handle, the area root class, and the catalog class. a) See the source code excerpt from the model solution. 3. Create an area, an instance of the catalog class, and an instance of the area root class. Set up the area. Read the necessary catalog data from tables SPFLI and SFLIGHT. a) See the source code excerpt from the model solution. 4. Don’t forget to delete the write lock after the data is written successfully. a) See the source code excerpt from the model solution. 5. Execute the program and then use the Shared Objects Monitor to examine the shared memory area. a) Execute the program and then run transaction SHMM to examine the details of the shared memory area instance.
470
© Copyright . All rights reserved.
Lesson: Using Shared Objects
Task 4 Implement a read program to read data from the area you just created (suggested name: ZBC402_##_READ_CATALOG). Output the data in a simple user dialog (using the provided function module BC402_DISPLAY_TABLE, for example). 1. Create an executable program. a) Carry out this step in the usual manner. 2. Define a selection screen in which the user can enter the departure and destination cities. The user should also be able to enter an earliest and latest possible flight date. a) See the source code excerpt from the model solution. 3. Make sure the data is read from the catalog object. Output the data in the user dialog. a) See the source code excerpt from the model solution. Class CL_BC402_SHS_CATALOG: Implementation
METHOD fill_catalog. gt_catalog = it_catalog. ENDMETHOD. METHOD get_flights. FIELD-SYMBOLS: TYPE sdyn_conn. LOOP AT gt_catalog ASSIGNING WHERE cityfrom cityto fldate fldate
= = > <
iv_from_city AND iv_to_city AND iv_earliest AND iv_latest.
APPEND TO et_flights. ENDLOOP. ENDMETHOD.
Program BC402_SHS_WRITE_CATALOG
REPORT
bc402_shs_write_catalog.
DATA: go_handle go_root
TYPE REF TO cl_bc402_shs_area, TYPE REF TO cl_bc402_shs_root,
© Copyright . All rights reserved.
471
Unit 10: Program Calls and Memory Management
go_catalog TYPE REF TO cl_bc402_shs_catalog, gt_flights TYPE
bc402_t_sdynconn.
START-OF-SELECTION. go_handle = cl_bc402_shs_area=>attach_for_write( ). CREATE OBJECT go_root AREA HANDLE go_handle. CREATE OBJECT go_catalog AREA HANDLE go_handle. go_root->mo_catalog = go_catalog. go_handle->set_root( root = go_root ). SELECT * FROM spfli JOIN sflight ON spfli~carrid = sflight~carrid AND spfli~connid = sflight~connid INTO CORRESPONDING FIELDS OF TABLE gt_flights. go_handle->root->mo_catalog->fill_catalog( it_catalog = gt_flights ). go_handle->detach_commit( ).
Program BC402_SHS_READ_CATALOG
REPORT
bc402_shs_read_catalog.
DATA: go_handle gt_flights gs_flight
TYPE REF TO TYPE LIKE LINE OF
cl_bc402_shs_area, bc402_t_sdynconn, gt_flights,
gv_startdate TYPE sydatum, gv_enddate TYPE sydatum. PARAMETERS: pa_from pa_to SELECT-OPTIONS: so_date
TYPE spfli-cityfrom, TYPE spfli-cityto. FOR sy-datum NO-EXTENSION.
AT SELECTION-SCREEN. READ TABLE so_date INDEX 1. IF so_date IS INITIAL. so_date-low = sy-datum. so_date-high = sy-datum + 365. ENDIF.
472
© Copyright . All rights reserved.
Lesson: Using Shared Objects
gv_startdate = sy-datum. gv_enddate = sy-datum + 365. IF so_date-low > sy-datum. gv_startdate = sy-datum. ENDIF. IF so_date-high < gv_enddate. gv_enddate = so_date-high. ENDIF. START-OF-SELECTION. go_handle = cl_bc402_shs_area=>attach_for_read( ). go_handle->root->mo_catalog->get_flights( EXPORTING iv_from_city = pa_from iv_to_city = pa_to iv_earliest = gv_startdate iv_latest = gv_enddate IMPORTING et_flights = gt_flights ). go_handle->detach( ). CALL FUNCTION 'BC402_DISPLAY_TABLE' CHANGING ct_table = gt_flights.
© Copyright . All rights reserved.
473
Unit 10: Program Calls and Memory Management
LESSON SUMMARY You should now be able to:
474
●
Explain shared objects
●
Use shared objects
© Copyright . All rights reserved.
Unit 10 Learning Assessment
1. Shared memory is a memory area on an application server that the ABAP programs running on that server can access. Determine whether this statement is true or false. X
True
X
False
2. Method __________ of the area handle is available for the application to release the read lock. Choose the correct answer. X
A DETACH_COMMIT
X
B OUTDATED
X
C DETACH
© Copyright . All rights reserved.
475
Unit 10 Learning Assessment - Answers
1. Shared memory is a memory area on an application server that the ABAP programs running on that server can access. Determine whether this statement is true or false. X
True
X
False
2. Method __________ of the area handle is available for the application to release the read lock. Choose the correct answer.
476
X
A DETACH_COMMIT
X
B OUTDATED
X
C DETACH
© Copyright . All rights reserved.
UNIT 11
Dynamic Programming
Lesson 1 Using Generic Data Types Exercise 26: Use Dynamically Typed Field Symbols in Dynamic SQL Statements Exercise 27: Access Structure Components Dynamically
478 485 495
Lesson 2 Describing Data Types, Data Objects, and Objects at Runtime Exercise 28: Provide Column Headers Using Runtime Type Identification
504 517
Lesson 3 Creating Data Types, Data Objects, and Objects at Runtime Exercise 29: Create Data Objects at Runtime Exercise 30: Create Data Types at Runtime with Runtime Type Creation (RTTC)
528 535 545
UNIT OBJECTIVES ●
Explain generic data types of ABAP
●
Use generic data types
●
Access data objects dynamically
●
Use generically typed data references
●
Explain the principle of RTTI
●
Describe data types and data objects at runtime
●
Describe object types and objects at runtime
●
Create objects (instances) at runtime
●
Create data objects at runtime
●
Create data types at runtime
© Copyright . All rights reserved.
477
Unit 11 Lesson 1 Using Generic Data Types
LESSON OVERVIEW This lesson discusses how to use generic data types in ABAP for dynamic programming. It also discusses the constraints posed on generic data references by the ABAP syntax and how these constraints affect generic data use. Business Example You need to develop a flexible application. You therefore want to find out about the generic data types in ABAP and learn how to type parameters, field symbols, and data references generically. For this reason, you require the following knowledge: ●
●
●
●
An understanding of generic types and their uses An understanding of how to use generically typed parameters, field symbols, and data references An understanding of how to use field symbols to access data objects dynamically An understanding of how to use field symbols to access attributes and structure components dynamically
LESSON OBJECTIVES After completing this lesson, you will be able to:
478
●
Explain generic data types of ABAP
●
Use generic data types
●
Access data objects dynamically
●
Use generically typed data references
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
ABAP Built-In Generic Data Types
Figure 183: Generic ABAP Data Types
The figure illustrates the predefined generic data types supported by ABAP syntax. In addition to complete data types, ABAP also features a number of generic data types. In contrast to complete types, you cannot use generic types to define the properties of data objects. You only use generic types to type formal parameters and field symbols. Note: Currently, the two built-in types, ... TYPE REF TO OBJECT and ... TYPE REF TO DATA are the only types available for typing reference variables generically. Generic ABAP Data Types – Internal Tables
Figure 184: Generic ABAP Data Types – Internal Tables
© Copyright . All rights reserved.
479
Unit 11: Dynamic Programming
Hint: Most generic types, such as clike, csequence, numeric, simple, and xsequence, are available as of SAP Web AS 6.10. Generic type decfloat is available as of SAP NetWeaver 7.0 EhP 2. The figure shows generic ABAP data types, which are compatible with the set of ABAP types. When you call a procedure, the system checks whether the type of the actual parameter is compatible with the type of the formal parameter. When you assign a generically typed field symbol, the syntax check tests whether the type of the data object is compatible with the generic type of the field symbol.
Note: The DATA type behaves in the same way as ANY. The differentiation is purely theoretical at this point. In the future, however, reference variables with type TYPE REF TO ANY to point data objects or instances of classes might be possible. The ANY TABLE, INDEX TABLE, SORTED TABLE, and other types are special generic data types that are only compatible with internal tables. You can restrict them to internal tables with a specific table type. However, the line type and key definition remain open.
Freely Defined Generic Table Types
Figure 185: Generic Table Types – User-Defined
In addition to these built-in generic table types, ABAP also contains generic table types that developers create as generic types. These generic table types are created either in the ABAP Dictionary or in the program source code, with the TYPES statement. The figure shows an example of locally defined generic table types. In these generic table types, you define the line type, but the table type and key definition remain open.
480
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
Note: To create appropriate generic types in the ABAP Dictionary, check the corresponding options under Access and Key. Apart from the generic table types, there are no user-defined generic table types in ABAP.
Generically Typed Parameters
Figure 186: Problems When Parameters Are Too General
When you generically type formal parameters of a procedure, such as subroutine, function module, or method, the procedure becomes more flexible. Use syntax check to ensure that the procedure handles the different types. The syntax check ensures that the system passes only actual parameters with compatible types to generically typed formal parameters. When generically typed parameters are addressed in ABAP statements, wait until runtime to determine whether the type of underlying data object or its current content is logical in the respective operand position. If conflicts occur, the system raises runtime errors that are not caught in most cases. The figure shows an example. If you assign an internal table or a structure that is not flat and character-type to a parameter, the WRITE statement raises an uncatchable exception, OBJECTS_NOT_CHARCONV. The syntax check helps avoid such runtime errors, particularly in operand positions that only allow internal tables, such as SELECT ... INTO TABLE ... and LOOP AT TABLE .... The syntax only accepts generic table types in these operand positions. Therefore, ensure that an internal table comes after the formal parameter. To avoid syntax errors and runtime errors, select generic types that are specific enough to be used with all compatible types in the desired operand position.
© Copyright . All rights reserved.
481
Unit 11: Dynamic Programming
Type Precisely to Avoid Errors
Figure 187: Avoiding Errors by Typing as Precisely as Possible
If you use the generic type SIMPLE, the WRITE statement does not cause runtime errors. You can convert all data types that are compatible with SIMPLE to a character string. The syntax errors are corrected because parameter it_data now accepts only internal tables because of its type, ANY TABLE.
Hint: A runtime error can still occur if the method contains an index access to it_data, specifically, if the actual parameter is a hashed table. Use the generic type INDEX TABLE to restrict the formal parameter even further.
482
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
Generically Typed Field Symbols
Figure 188: Example – Generic Field Symbol in Dynamic SELECT
Field symbols are pointers that you assign to data objects dynamically. While using the field symbol in an ABAP statement, dynamically define the specific data object that the field symbol refers to. If the field symbol is fully typed, then all potential data objects have the same type, which restricts the possible uses of field symbols significantly. Generic typing enables the field symbol to refer to data objects with different types. As a result, you can address different data objects in the same operand position of an ABAP statement. The figure shows an example of how to use a field symbol in a dynamic SELECT statement. To command the program to access one of two database tables, SCARR or SBOOK, depending on the content of data object lv_table_name, program a dynamic SELECT statement. To ensure that the line type of the internal table matches the field list of the database table, use a generically typed field symbol as a target that points to internal table lt_scarr or lt_sbook as required.
Hint: The field symbol cannot have type ANY. If you assign this type to the two internal tables without any problems, it causes a syntax error when used in the SELECT statement.
© Copyright . All rights reserved.
483
Unit 11: Dynamic Programming
Note: This example is only dynamic to an extent because data objects needs to be defined statically.
Type Casting for Field Symbols
Figure 189: Type Casting for Field Symbols
To remove the restrictions of the data object’s original type, use the CASTING addition to assign a data object to a field symbol. This field symbol has a different type. The data object is then interpreted as though it has the data type of the field symbol. To access the data object using the field symbol as if the object has an explicitly specified type, use the CASTING TYPE addition. The CASTING TYPE addition is used to assign a data object to a field symbol. This field symbol has a different type. In the figure, note that the system field is an elementary character-type component of length 8.
484
© Copyright . All rights reserved.
Unit 11 Exercise 26 Use Dynamically Typed Field Symbols in Dynamic SQL Statements
Business Example You need to develop a simple program that displays the contents of any database table. Find out about the options available in dynamic programming. Define the database table in a SELECT statement dynamically, and use a generically typed field symbol to specify the target range of a SELECT statement dynamically. Task 1 Copy program BC402_DYS_DYN_CALL or your own program ZBC402_##_DYN_CALL and name it ZBC402_##_DYN_SQL, where ## is your group number. Familiarize yourself with the program and how it works. 1. Copy the program and all its subcomponents. 2. Activate and test the program. Analyze the source code. How is the data read from the database and into which data objects is it filled?
Task 2 Replace the two SELECT statements with a single SELECT statement after the ENDCASE statement. Specify the table name as a character-type data object. In addition, use a generically typed field symbol as the target range (INTO clause) to which you dynamically assign a suitable data object. 1. Define a character-type data object for the table name (suggested name is gv_tabname). Fill the data object with the respective table names in the WHEN blocks. 2. Create a field symbol (suggested name is ) whose type is assigned as either data object gt_conn or gt_cust. 3. Why is type ANY not suitable? 4. Assign the field symbol to the respective internal tables in the WHEN blocks, the ones you want to fill in the generic SELECT statement. 5. Move one of the two SELECT statements from the WHEN block to after the ENDCASE statement and delete the other one. Make the remaining database access dynamic. Replace the static table name with data object gv_tabname and replace the target range (internal table) with the field symbol.
© Copyright . All rights reserved.
485
Unit 11: Dynamic Programming
Task 3 Optional Catch the specific runtime errors that occur when using dynamic SQL statements. 1. Read the keyword documentation to find out about the exceptions that occur when using dynamic SQL statements. Implement exception handling with TRY... CATCH ... ENDTRY. Either implement a separate CATCH block for each of the exception classes or use a single CATCH block for the shared superclass. If an error occurs, respond with error message 061 from message class BC402.
486
© Copyright . All rights reserved.
Unit 11 Solution 26 Use Dynamically Typed Field Symbols in Dynamic SQL Statements
Business Example You need to develop a simple program that displays the contents of any database table. Find out about the options available in dynamic programming. Define the database table in a SELECT statement dynamically, and use a generically typed field symbol to specify the target range of a SELECT statement dynamically. Task 1 Copy program BC402_DYS_DYN_CALL or your own program ZBC402_##_DYN_CALL and name it ZBC402_##_DYN_SQL, where ## is your group number. Familiarize yourself with the program and how it works. 1. Copy the program and all its subcomponents. a) Perform this step as usual. 2. Activate and test the program. Analyze the source code. How is the data read from the database and into which data objects is it filled? a) The data is read from the database in static SELECT statements. In the process, one of two statically defined internal tables is filled.
Task 2 Replace the two SELECT statements with a single SELECT statement after the ENDCASE statement. Specify the table name as a character-type data object. In addition, use a generically typed field symbol as the target range (INTO clause) to which you dynamically assign a suitable data object. 1. Define a character-type data object for the table name (suggested name is gv_tabname). Fill the data object with the respective table names in the WHEN blocks. a) See the source code excerpt from the model solution. 2. Create a field symbol (suggested name is ) whose type is assigned as either data object gt_conn or gt_cust. a) See the source code excerpt from the model solution. 3. Why is type ANY not suitable?
© Copyright . All rights reserved.
487
Unit 11: Dynamic Programming
a) The field symbol should be specified after INTO TABLE in the SELECT statement. The syntax check only allows generic values here, with at least type ANY TABLE. 4. Assign the field symbol to the respective internal tables in the WHEN blocks, the ones you want to fill in the generic SELECT statement. a) See the source code excerpt from the model solution. 5. Move one of the two SELECT statements from the WHEN block to after the ENDCASE statement and delete the other one. Make the remaining database access dynamic. Replace the static table name with data object gv_tabname and replace the target range (internal table) with the field symbol. a) See the source code excerpt from the model solution.
Task 3 Optional Catch the specific runtime errors that occur when using dynamic SQL statements. 1. Read the keyword documentation to find out about the exceptions that occur when using dynamic SQL statements. Implement exception handling with TRY... CATCH ... ENDTRY. Either implement a separate CATCH block for each of the exception classes or use a single CATCH block for the shared superclass. If an error occurs, respond with error message 061 from message class BC402. a) See the source code excerpt from the model solution. REPORT
bc402_dys_dyn_sql MESSAGE-ID bc402.
TYPE-POOLS: abap. DATA: gt_cust gt_conn
TYPE ty_customers, TYPE ty_connections.
DATA: gv_methname TYPE string, gt_parmbind TYPE abap_parmbind_tab, gs_parmbind TYPE abap_parmbind. DATA: gv_tabname
TYPE string.
FIELD-SYMBOLS: TYPE ANY TABLE. SELECTION-SCREEN COMMENT 1(80) text-sel. PARAMETERS: pa_xconn TYPE xfeld RADIOBUTTON GROUP tab DEFAULT 'X', pa_xcust TYPE xfeld RADIOBUTTON GROUP tab . PARAMETERS: pa_nol TYPE i DEFAULT '100'.
488
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
START-OF-SELECTION. * specific part *------------------------------------------* CASE 'X'. WHEN pa_xconn. gv_tabname = 'SPFLI'. ASSIGN gt_conn TO . gv_methname = 'WRITE_CONNECTIONS'. gs_parmbind-name = 'IT_CONN'. GET REFERENCE OF gt_conn INTO gs_parmbind-value. INSERT gs_parmbind INTO TABLE gt_parmbind. WHEN pa_xcust. gv_tabname = 'SCUSTOM'. ASSIGN gt_cust TO . gv_methname = 'WRITE_CUSTOMERS'. gs_parmbind-name = 'IT_CUST'. GET REFERENCE OF gt_cust INTO gs_parmbind-value. INSERT gs_parmbind INTO TABLE gt_parmbind. ENDCASE. * dynamic part *---------------------------------------------* TRY.
SELECT * FROM (gv_tabname) INTO TABLE UP TO pa_nol ROWS. CATCH cx_sy_dynamic_osql_error. MESSAGE e061. ENDTRY. TRY.
CALL METHOD cl_bc402_utilities=>(gv_methname) PARAMETER-TABLE gt_parmbind.
CATCH cx_sy_dyn_call_error. MESSAGE e060. ENDTRY.
© Copyright . All rights reserved.
489
Unit 11: Dynamic Programming
Dynamic Access to Data Objects
Figure 190: Dynamic Access to Data Objects
In most ABAP statements, do not replace data objects in operand positions directly with character-type data objects in parentheses. Instead, use the ASSIGN statement for the data object to which you need to assign the field symbol. Use this approach to address the data object dynamically by its name. Assign a generically typed field symbol to the data object using the syntax shown in the figure, and then use the field symbol in the ABAP statement. You can also use easier, less error-prone alternatives to access attributes and structure components.
490
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
Dynamic Access to Instance Attributes and Class Attributes
Figure 191: Dynamic Access to Object Attributes and Class Attributes
In addition to using the full identifier for dynamic access to attributes of classes and instance, use another variant to specify the attribute name solely with a character-type data object. Specify the object reference and component selector statically. You also specify the class name for static attributes dynamically, if necessary. This syntax is similar to that for dynamic method calls.
Hint: Because the syntax check supports the static part of the statement, these variants are less error-prone and are therefore preferred.
© Copyright . All rights reserved.
491
Unit 11: Dynamic Programming
Dynamic Access to Structure Components
Figure 192: Dynamic Access to Structure Components
Use a special variant of the ASSIGN statement to access structure components dynamically. You specify the structure statically or through a separate field symbol in the ASSIGN COMPONENT ... OF STRUCTURE ... statement. Address the components either by name or by position (number) within the structure. Hint: Because the syntax check supports the static part of the statement, these variants are less error-prone and are therefore preferred. Because the system addresses the components of a structure by their positions in sequence, you can process any structure completely, component by component.
492
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
Full Processing of Any Non-Nested, Flat Structure
Figure 193: Full Processing of Any Non-Nested, Flat Structure
Caution: In the figure, an uncatchable ASSIGN_TYPE_CONFLICT runtime error occurs if the transferred structure contains a component that is incompatible with the generic SIMPLE type of the field symbols. Similarly, a runtime error occurs during the WRITE statement when you type the field symbol with ANY.
© Copyright . All rights reserved.
493
Unit 11: Dynamic Programming
494
© Copyright . All rights reserved.
Unit 11 Exercise 27 Access Structure Components Dynamically
Business Example You need to develop a simple program that displays the contents of any database table. You therefore want to find out about the options available in dynamic programming. To implement a generic method that enables you to output the contents of any table in a list (provided the line type of the internal table has a flat structure), replace the dynamic call of two specific methods with a static call of a generic method. Use generically typed interface parameters, generically typed field symbols, and access structure components dynamically. Task 1 Copy global class CL_BC402_DYT_GEN_TYPES and name it ZCL_BC402_##_GEN_TYPES, where ## is your group number. Familiarize yourself with the class signature. 1. Copy the global class. 2. Analyze the class signature. Which methods are defined? What is their purpose? 3. Which parameters do these methods have? How are the parameters typed?
Task 2 Implement method write_any_struct, and output all components of structure gs_struct individually with a WRITE statement by programming a loop in which you access all the components in structure gs_struct consecutively. 1. Create a field symbol (suggested name is ) that has a generic type that allows assignment of any flat components of the structure. 2. Program a DO loop. Use the sy-index loop counter to access all components of gs_struct consecutively with the field symbol. 3. Check whether the field symbol assignment was successful. If it was, output the component with a WRITE statement. Otherwise, exit the loop.
Task 3 Implement method write_any_table. Display the contents of internal table it_table in a list by lines by programming a loop over internal table gt_table. Call your previously implemented method, write_any_struct, for each line.
© Copyright . All rights reserved.
495
Unit 11: Dynamic Programming
1. Create a field symbol (suggested name is ) that has a generic type that allows assignment of a line of generic internal table it_table. 2. Program a LOOP over internal table it_table. Assign the lines in the internal table to field symbol consecutively. 3. Call method write_any_struct for each line.
Task 4 Copy program BC402_DYS_DYN_SQL or your own program ZBC402_##_DYN_SQL and name it ZBC402_##_GEN_TYPES, where ## is your group number. Familiarize yourself with the program and how it works. 1. Copy the program and all its subcomponents. 2. Activate and test the program. Analyze the source code.
Task 5 Replace the dynamic method call at the end of the program with a call of your new method, write_any_table. Remove all parts of the source code you no longer need, or flag them as comments. 1. Delete the dynamic method call or flag it as a comment. In its place, implement a call of method write_any_table. Give the method the generic field symbol that points to the internal table with the data. 2. Delete the definitions of the data objects that are needed for the dynamic method call or flag them as comments. 3. Activate and test the program.
496
© Copyright . All rights reserved.
Unit 11 Solution 27 Access Structure Components Dynamically
Business Example You need to develop a simple program that displays the contents of any database table. You therefore want to find out about the options available in dynamic programming. To implement a generic method that enables you to output the contents of any table in a list (provided the line type of the internal table has a flat structure), replace the dynamic call of two specific methods with a static call of a generic method. Use generically typed interface parameters, generically typed field symbols, and access structure components dynamically. Task 1 Copy global class CL_BC402_DYT_GEN_TYPES and name it ZCL_BC402_##_GEN_TYPES, where ## is your group number. Familiarize yourself with the class signature. 1. Copy the global class. a) Carry out this step as usual. 2. Analyze the class signature. Which methods are defined? What is their purpose? a) write_any_struct and write_any_table for list output of any flat structure or any internal table with flat line type. 3. Which parameters do these methods have? How are the parameters typed? a) The two parameters are gs_struct TYPE ANY and gt_struct TYPE ANY TABLE.
Task 2 Implement method write_any_struct, and output all components of structure gs_struct individually with a WRITE statement by programming a loop in which you access all the components in structure gs_struct consecutively. 1. Create a field symbol (suggested name is ) that has a generic type that allows assignment of any flat components of the structure. a) See the source code excerpt from the model solution. 2. Program a DO loop. Use the sy-index loop counter to access all components of gs_struct consecutively with the field symbol. a) See the source code excerpt from the model solution. 3. Check whether the field symbol assignment was successful. If it was, output the component with a WRITE statement. Otherwise, exit the loop.
© Copyright . All rights reserved.
497
Unit 11: Dynamic Programming
a) See the source code excerpt from the model solution.
Task 3 Implement method write_any_table. Display the contents of internal table it_table in a list by lines by programming a loop over internal table gt_table. Call your previously implemented method, write_any_struct, for each line. 1. Create a field symbol (suggested name is ) that has a generic type that allows assignment of a line of generic internal table it_table. a) See the source code excerpt from the model solution. 2. Program a LOOP over internal table it_table. Assign the lines in the internal table to field symbol consecutively. a) See the source code excerpt from the model solution. 3. Call method write_any_struct for each line. a) See the source code excerpt from the model solution.
Task 4 Copy program BC402_DYS_DYN_SQL or your own program ZBC402_##_DYN_SQL and name it ZBC402_##_GEN_TYPES, where ## is your group number. Familiarize yourself with the program and how it works. 1. Copy the program and all its subcomponents. a) Perform this step as usual. 2. Activate and test the program. Analyze the source code. a) Perform this step as usual.
Task 5 Replace the dynamic method call at the end of the program with a call of your new method, write_any_table. Remove all parts of the source code you no longer need, or flag them as comments. 1. Delete the dynamic method call or flag it as a comment. In its place, implement a call of method write_any_table. Give the method the generic field symbol that points to the internal table with the data. a) See the source code excerpt from the model solution. 2. Delete the definitions of the data objects that are needed for the dynamic method call or flag them as comments. a) See the source code excerpt from the model solution. 3. Activate and test the program.
498
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
a) Perform this step as usual. Method write_any_struct (Class CL_BC402_DYS_GEN_TYPE) method WRITE_ANY_STRUCT. FIELD-SYMBOLS TYPE simple. NEW-LINE. DO. ASSIGN COMPONENT sy-index OF STRUCTURE is_struct TO . IF sy-subrc = 0. WRITE . ELSE. EXIT. ENDIF. ENDDO. endmethod. Method write_any_table (Class CL_BC402_DYS_GEN_TYPE) method WRITE_ANY_TABLE. FIELD-SYMBOLS: TYPE ANY. LOOP AT it_table ASSIGNING . write_any_struct( ). ENDLOOP. endmethod. Executable Program BC402_DYS_GEN_TYPES REPORT
bc402_dys_gen_types MESSAGE-ID bc402.
*TYPE-POOLS: abap. DATA: gt_cust gt_conn
TYPE ty_customers, TYPE ty_connections.
*DATA: * gv_methname TYPE string, * gt_parmbind TYPE abap_parmbind_tab, * gs_parmbind TYPE abap_parmbind. DATA: gv_tabname
TYPE string.
FIELD-SYMBOLS: TYPE ANY TABLE. SELECTION-SCREEN COMMENT 1(80) text-sel.
© Copyright . All rights reserved.
499
Unit 11: Dynamic Programming
PARAMETERS: pa_xconn TYPE xfeld RADIOBUTTON GROUP tab DEFAULT 'X', pa_xcust TYPE xfeld RADIOBUTTON GROUP tab . PARAMETERS: pa_nol TYPE i DEFAULT '100'. START-OF-SELECTION. * specific part *----------------------------------------------------* CASE 'X'. WHEN pa_xconn. gv_tabname = 'SPFLI'. ASSIGN gt_conn TO . WHEN pa_xcust. gv_tabname = 'SCUSTOM'. ASSIGN gt_cust TO . ENDCASE. * dynamic part *------------------------------------------------------* TRY.
SELECT * FROM (gv_tabname) INTO TABLE UP TO pa_nol ROWS. CATCH cx_sy_dynamic_osql_error. MESSAGE e061. ENDTRY. * * * * * * * *
TRY.
CALL METHOD cl_bc402_utilities=>(gv_methname) PARAMETER-TABLE gt_parmbind.
CATCH cx_sy_dyn_call_error. MESSAGE e060. ENDTRY. cl_bc402_dys_gen_types=>write_any_table( fs_table ).
500
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
Generically Typed Data References You can type reference variables generically. However, in contrast to field symbols, only the generic types DATA (for data references) and OBJECT (for object references) are available for reference variables. The use of generically typed reference variables is restricted in ABAP. With the exception of the ASSIGN statement, generically typed reference variables cannot be dereferenced directly in operand positions. The statement WRITE ref->* has incorrect syntax, for example, if the data reference has type TYPE REF TO DATA. Due to these restrictions, you use generic data references only where generic field symbols do not work.
Use Cases for Generically Typed Data References The options for addressing the contents of the referenced data object for references with type TYPE REF TO DATA are as follows: ●
In internal tables
●
During the dynamic generation of data objects using the CREATE DATA statement
Cast Assignment for Data References
Figure 194: Cast Assignment for Data References
To address the content of referenced data objects, use a fully typed data reference. The contents of the generic data reference are copied to the fully typed data reference. You can then dereference the complete data reference in any operand item.
© Copyright . All rights reserved.
501
Unit 11: Dynamic Programming
However, for this technique to work, the second reference variable needs to have the same type as the referenced data object. When you assign values between two reference variables with different types, you perform a cast assignment. It is similar to cast assignment between object references, which you learned about during object-oriented programming. As with object references, an up cast occurs when the target variable has a more general definition, and a down cast occurs when the target variable has a more specific type than the source variable. Accordingly, assignment from a generic data reference to a full reference is a down cast. While up casts to type TYPE REF TO DATA always work, the down cast must have the ?= cast operator to have proper syntax. The system checks compatibility at runtime in this case.
Caution: If the type of the new reference variable does not match the exact type of the referenced data object, a runtime error occurs. Class CX_SY_MOVE_CAST_ERROR is an exception.
Dereferenced Generically Typed Data References
Figure 195: Dereferencing Generically Typed Data References
The only ABAP statement in which you can dereference a generic reference variable is the ASSIGN statement. The ASSIGN statement assigns a (generic) field symbol to the data object to which the generic reference variable points. You then address and further process the contents of the referenced object using this field symbol.
502
© Copyright . All rights reserved.
Lesson: Using Generic Data Types
LESSON SUMMARY You should now be able to: ●
Explain generic data types of ABAP
●
Use generic data types
●
Access data objects dynamically
●
Use generically typed data references
© Copyright . All rights reserved.
503
Unit 11 Lesson 2 Describing Data Types, Data Objects, and Objects at Runtime
LESSON OVERVIEW This lesson discusses runtime type identification (RTTI), a technique that you use to query information about data types and object types at runtime. This technique is essential to use the generically typed parameters, field symbols, and references in dynamic programs. Business Example You need to develop a flexible application using generically typed parameters, field symbols, and references. You therefore want to learn about the options provided by RTTI for querying information about the actual type of the underlying object at runtime. For this reason, you require the following knowledge: ●
An understanding of how to query the properties of data objects and data types at runtime
●
An understanding of how to query the properties of classes and instances at runtime
LESSON OBJECTIVES After completing this lesson, you will be able to:
504
●
Explain the principle of RTTI
●
Describe data types and data objects at runtime
●
Describe object types and objects at runtime
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
RTTI Class Hierarchy
Figure 196: Class Hierarchy of RTTI Description Classes
As of SAP Web AS 6.10, ABAP developers use a class-based concept, RTTI, to determine type properties, such as data types and object types, at runtime. Hint: Before RTTI, ABAP contained only the DESCRIBE FIELD and DESCRIBE TABLE statements. However, these statements are limited to properties of data objects, and do not determine as many properties as RTTI. RTTI consists of a hierarchy of ten global classes that developers use. The description of a type at runtime is an instance of one of these global classes. The instance attributes save the properties of the type. You query them directly or by using appropriate methods. At runtime, only one description object exists for each type. All classes inherit properties from a shared superclass, either directly or indirectly, and their names all follow the pattern CL_ABAP_xxxDESCR, where xxx stands for the category of the type used to describe the respective class. You need different classes because the attributes and methods of each class specialize to describe a specific category of types. For example, you use class CL_ABAP_TABLEDESCR to describe table types. Therefore, the class contains attributes for the table category and the structure of the table key, among other information. These attributes are specific to class CL_ABAP_TABLEDESCR. No other RTTI classes contain them. RTTI Classes – Purpose
© Copyright . All rights reserved.
505
Unit 11: Dynamic Programming
You can instantiate only six of the ten RTTI classes and use them to describe specific types. The following table lists the RTTI classes that you can instantiate with their purposes: RTTI Class
Purpose
CL_ABAP_ELEMDESCR
To describe elementary data types
CL_ABAP_REFDESCR
To describe reference types (= types of reference variables)
CL_ABAP_STRUCTDESCR
To describe structure types
CL_ABAP_TABLEDESCR
To describe table types
CL_ABAP_CLASSDESCR
To describe classes (= object types)
CL_ABAP_INTFESCR
To describe interfaces
All other classes are abstract, which means that you cannot instantiate them. Use those classes to define the attributes and methods that are used in several of the other classes and implement them if necessary. For example, the METHODS attribute, which contains a list of the methods, is not defined in class CL_ABAP_CLASSDESCR, but instead in class CL_ABAP_OBJECTDESCR, because it is also needed in the same form in class CL_ABAP_INTFDESCR.
Figure 197: RTTI classes you can instantiate
506
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
RTTI Class Instantiation
Figure 198: RTTI – Methods and Attributes of the Root Class
Do not instantiate the RTTI description classes directly with the CREATE OBJECT statement. To retrieve a reference to a description object, call static method DESCRIBE_BY_xxx of class CL_ABAP_TYPEDESCR. The description objects are generated and the data is filled and returned using a return parameter with generic type REF TO CL_ABAP_TYPEDESCR.
© Copyright . All rights reserved.
507
Unit 11: Dynamic Programming
Describe a Type Based on Its Name
Figure 199: Describing a Type Based on Its Name
After the call, you need to cast a suitable subclass to access specific attributes and methods for the respective type. If you do not know which RTTI class was instantiated, evaluate the public KIND instance attribute whose contents match the value of one of the six constants from class CL_ABAP_TYPEDESCR. Each of these six constants corresponds to one of the six RTTI classes that the developer can instantiate.
508
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
Suitable Reference for a Type Description Object
Figure 200: Casing a Suitable Reference for a Type Description Object
Hint: If you know which description class is instantiated, then the down cast can also take place directly in the call of the functional method, for example, lo_class?= cl_abap_typedescr=>describe_by_... In this case, you can catch runtime error CX_SY_MOVE_CAST_ERROR. Methods for Description Objects The following methods differ with regard to the information they are given in their calls: DESCRIBE_BY_NAME
●
This method returns the description object with the type name that you specify and analyzes both data types and object types (classes and interfaces) that are defined globally in the ABAP Dictionary or Class Builder, or locally in the program. You must enter the type name in upper case. If the method does not find the type with the specified name, it raises a conventional exception TYPE_NOT_FOUND. ●
DESCRIBE_BY_DATA This method returns the description object for the type of a data object. It only returns descriptions of data types, and it does not consider whether the data object was defined with an explicit type or a bound type.
© Copyright . All rights reserved.
509
Unit 11: Dynamic Programming
If the specified data object is a parameter or field symbol with a generic type, the method does not return the description of the generic type. Instead, it returns the type of the currently assigned actual parameter or data object. ●
DESCRIBE_BY_DATA_REF This method returns the description object for the type of a data object that points to a data reference. It only returns descriptions of data types. If the data reference is typed generically (TYPE REF TO DATA), you can use this method to determine the dynamic type of the referenced object.
Caution: If the reference does not have a valid value at call time, the method raises conventional exception REFERENCE_IS_INITIAL. ●
DESCRIBE_BY_OBJECT_REF This method returns the description object for the type of an instance that points to an object reference. It only returns descriptions of classes. Use this method to determine the dynamic type of the referenced instance after an up cast to a superclass or implemented interface.
Caution: If the reference does not have a valid value at call time, the method raises conventional exception REFERENCE_IS_INITIAL.
510
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
Describe Types Based on Data Objects and References
Figure 201: Describing Types Based on Data Objects and References
The figure shows examples to use these static methods. In addition to static methods, you use special methods to navigate from one description object to other description objects. For example, you want to navigate from the description of a table type to the description of the corresponding line type, or you want to navigate from a structure type to the description objects for the component types.
© Copyright . All rights reserved.
511
Unit 11: Dynamic Programming
Elementary Data Type Analysis
Figure 202: Analysis of an Elementary Data Type
The application examples demonstrate how to use RTTI to determine the properties of different data types. Whether the system uses a given subclass depends on the data type. An instance of class CL_ABAP_ELEMDESCR describes all the properties of an elementary data type. The corresponding public attributes contain the technical properties of the underlying ABAP type, the length, and the number of decimal places. To evaluate the TYPE_KIND attribute, compare its contents with the corresponding constants from class CL_ABAP_TYPEDESCR, as you must do to evaluate the KIND attribute.
Note: The three attributes are described in the root class of RTTI, which means they are inherited by all description classes. However, in the other classes, these attributes are less significant. The semantic properties, that is, the additional information from the ABAP Dictionary, must be determined explicitly using public methods. The figure shows a call of method GET_DDIC_FIELD. You use an optional parameter to determine language-dependent information, such as field labels, in a language other than the current logon language.
512
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
Caution: If the current type is not a dictionary type, the method raises a conventional exception. To avoid this, use method IS_DDIC_TYPE to check whether dictionary information is available (see the example given in the figure).
Reference Type Analysis
Figure 203: Analysis of the Type of a Reference Variable
When you analyze a reference type (= type of a reference variable), the inherited TYPE_KIND attribute allows you to differentiate between object references and data references. However, to determine the details of the static type of the reference variable, use the GET_REFERENCED_TYPE navigation method. This method returns a reference to another description object. This description object can be an instance of class CL_ABAP_STRUCTDESCR if the reference variable was created with a structure type. However, if you create the reference variable with reference to a class or an interface, then GET_REFERENCED_TYPE returns instances of the CL_ABAP_CLASSDESCR or CL_ABAP_INTFDESCR class, respectively.
© Copyright . All rights reserved.
513
Unit 11: Dynamic Programming
Structure Type Analysis
Figure 204: Navigation from Structure Type to Component Types
To gain full access to all properties of the component types, navigate to the respective description objects. The GET_COMPONENT_TYPE navigation method returns the description object for the type of a specific component, while the GET_COMPONENTS navigation method returns the description objects for all components.
Hint: Because component types are also reference types, structure types, or table types, define the return values with type REF TO CL_ABAP_DATADESCR. A down cast to one of the subclasses may be necessary in reference variables, for example, to type REF TO CL_ABAP_ELEMDESCR.
514
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
Table Type Analysis
Figure 205: Analysis of a Table Type
The public attributes of class CL_ABAP_TABLEDESCR include the table types such as standard, sorted, hashed, index, any, uniqueness of the key, and a list of names of the key components. To determine the details for a line type, navigate to a description object for that line type the GET_TABLE_LINE_TYPE navigation method. Hint: The line type of a table type can have any data type. Accordingly, the return parameter is typed with REF TO CL_ABAP_DATADESCR and performs a down cast to a suitable type if necessary.
© Copyright . All rights reserved.
515
Unit 11: Dynamic Programming
516
© Copyright . All rights reserved.
Unit 11 Exercise 28 Provide Column Headers Using Runtime Type Identification
Business Example You need to develop a simple program that displays the contents of any database table. To develop the program, you need to find out about the options available in dynamic programming. You have already developed a method to output any internal table with a flat line type to a list. You need to use the options of RTTI to develop a method that generates dynamic column headers for the program. Use RTTI to analyze a structure type and to determine semantic information for that structure type from the ABAP Dictionary. Use the semantic information for the structure type to generate column headers dynamically. Task 1 Copy template CL_BC402_DYT_RTTI_HEADERS and name it ZCL_BC402_##_RTTI_HEADERS, where ## is your group number. Familiarize yourself with the class signature. 1. Copy the global class. 2. Analyze the class signature. Determine which methods are defined and what their purposes are? 3. Which parameters and exceptions do these methods have? How are the parameters typed? Which error situations correspond to the exceptions?
Task 2 Implement method write_headers. Use RTTI options to analyze the type of which the name is contained in import parameter gv_tabname. 1. Call a suitable static method of class CL_ABAP_TYPEDESCR to analyze the data type based on its name. 2. Create a local reference variable (suggested name is lo_type) and enter it to match the return parameter of the method. Specify this reference variable as an actual parameter in the method call. 3. Handle any possible exceptions and raise exception TYPE_NOT_FOUND from method write_headers as a reaction.
© Copyright . All rights reserved.
517
Unit 11: Dynamic Programming
4. Use the public KIND attribute to determine whether the generated RTTI instance actually describes a structure type. If the data type is not a structure type, exit method write_headers with exception NO_STRUCTURE. 5. Create a local reference variable (suggested name is lo_struct) and assign it to a type so that it points to instances of class CL_ABAP_STRUCTDESCR. Program a down cast to point this reference to the type description object. Hint: Do not catch possible runtime errors here because the query of the KIND attribute already ensures compatibility.
Task 3 Determine a list with dictionary information for all components of the structure type. Output the report header for all components in sequence. Ensure that the output does not exceed the display length of the corresponding field. 1. Create an internal table with type ddfields (suggested name: lt_fields). 2. Call a suitable method of class CL_ABAP_STRUCTDESCR to generate a list with dictionary information for the structure components. To do so, create an internal table with type ddfields as the actual parameter for the return value (suggested name is lt_fields). If the method call terminates with exceptions, exit the write_headers method with a suitable exception. 3. To program a loop over the internal table, create a field symbol (suggested name is ) that is typed with the line type of internal table lt_fields. 4. Output the report header (field reptext) in each loop pass. Use the output length (field outputlen) for length access to ensure the headers are exactly as long as they will be output later.
Task 4 Copy program BC402_DYS_GEN_TYPES or your own program, ZBC402_##_GEN_TYPES and name it ZBC402_##_RTTI_HEADERS, where ## is your group number. Familiarize yourself with the program and how it works. 1. Copy the program and all its subcomponents. 2. Activate and test the program. Analyze the source code.
Task 5 Insert a call of method write_headers before the data output. Pass the name of the line type of the internal table with the data to your method.
518
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
1. Implement a call of method write_headers before the call of method write_any_table. Pass the data object that contains the name of the database table (and therefore the name of the line type of the internal table). 2. React to exceptions with suitable error messages from message class BC402. 3. Activate and test the program.
© Copyright . All rights reserved.
519
Unit 11 Solution 28 Provide Column Headers Using Runtime Type Identification
Business Example You need to develop a simple program that displays the contents of any database table. To develop the program, you need to find out about the options available in dynamic programming. You have already developed a method to output any internal table with a flat line type to a list. You need to use the options of RTTI to develop a method that generates dynamic column headers for the program. Use RTTI to analyze a structure type and to determine semantic information for that structure type from the ABAP Dictionary. Use the semantic information for the structure type to generate column headers dynamically. Task 1 Copy template CL_BC402_DYT_RTTI_HEADERS and name it ZCL_BC402_##_RTTI_HEADERS, where ## is your group number. Familiarize yourself with the class signature. 1. Copy the global class. a) Perform this step as usual. 2. Analyze the class signature. Determine which methods are defined and what their purposes are? a) write_headers to output a list of column headers based on a structure type from the ABAP Dictionary. 3. Which parameters and exceptions do these methods have? How are the parameters typed? Which error situations correspond to the exceptions? a) Parameter iv_tabname with generic type csequence and exceptions. Error situations that correspond to the exceptions are as follows: ●
TYPE_NOT_FOUND The passed on type is unknown.
●
NO_STRUCTURE The object is not a structure type.
●
NO_DDIC_TYPE The object is not a type in the ABAP Dictionary.
520
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
Task 2 Implement method write_headers. Use RTTI options to analyze the type of which the name is contained in import parameter gv_tabname. 1. Call a suitable static method of class CL_ABAP_TYPEDESCR to analyze the data type based on its name. a) See the source code excerpt from the model solution. 2. Create a local reference variable (suggested name is lo_type) and enter it to match the return parameter of the method. Specify this reference variable as an actual parameter in the method call. a) See the source code excerpt from the model solution. 3. Handle any possible exceptions and raise exception TYPE_NOT_FOUND from method write_headers as a reaction. 4. Use the public KIND attribute to determine whether the generated RTTI instance actually describes a structure type. If the data type is not a structure type, exit method write_headers with exception NO_STRUCTURE. a) See the source code excerpt from the model solution. 5. Create a local reference variable (suggested name is lo_struct) and assign it to a type so that it points to instances of class CL_ABAP_STRUCTDESCR. Program a down cast to point this reference to the type description object. Hint: Do not catch possible runtime errors here because the query of the KIND attribute already ensures compatibility. a) See the source code excerpt from the model solution.
Task 3 Determine a list with dictionary information for all components of the structure type. Output the report header for all components in sequence. Ensure that the output does not exceed the display length of the corresponding field. 1. Create an internal table with type ddfields (suggested name: lt_fields). a) See the source code excerpt from the model solution. 2. Call a suitable method of class CL_ABAP_STRUCTDESCR to generate a list with dictionary information for the structure components. To do so, create an internal table with type ddfields as the actual parameter for the return value (suggested name is lt_fields). If the method call terminates with exceptions, exit the write_headers method with a suitable exception. a) See the source code excerpt from the model solution.
© Copyright . All rights reserved.
521
Unit 11: Dynamic Programming
3. To program a loop over the internal table, create a field symbol (suggested name is ) that is typed with the line type of internal table lt_fields. a) See the source code excerpt from the model solution. 4. Output the report header (field reptext) in each loop pass. Use the output length (field outputlen) for length access to ensure the headers are exactly as long as they will be output later. a) See the source code excerpt from the model solution.
Task 4 Copy program BC402_DYS_GEN_TYPES or your own program, ZBC402_##_GEN_TYPES and name it ZBC402_##_RTTI_HEADERS, where ## is your group number. Familiarize yourself with the program and how it works. 1. Copy the program and all its subcomponents. a) Perform this step in the usual way. 2. Activate and test the program. Analyze the source code. a) Perform this step in the usual way.
Task 5 Insert a call of method write_headers before the data output. Pass the name of the line type of the internal table with the data to your method. 1. Implement a call of method write_headers before the call of method write_any_table. Pass the data object that contains the name of the database table (and therefore the name of the line type of the internal table). a) See the source code excerpt from the model solution. 2. React to exceptions with suitable error messages from message class BC402. a) See the source code excerpt from the model solution. 3. Activate and test the program. a) Perform this step as usual. Method write_headers (Class_CL_BC402_DYS_RTTI_HEADERS) METHOD write_headers. DATA: lo_type TYPE REF TO cl_abap_typedescr, lo_struct TYPE REF TO cl_abap_structdescr, lt_flist TYPE ddfields. FIELD-SYMBOLS: LIKE LINE OF lt_flist.
522
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
CALL METHOD cl_abap_typedescr=>describe_by_name EXPORTING p_name = iv_tabname RECEIVING p_descr_ref = lo_type EXCEPTIONS type_not_found = 1. IF sy-subrc 0. RAISE type_not_found. ENDIF. IF lo_type->kind cl_abap_typedescr=>kind_struct. RAISE no_structure. ENDIF. lo_struct ?= lo_type. CALL METHOD lo_struct->get_ddic_field_list RECEIVING p_field_list = lt_flist EXCEPTIONS not_found = 1 no_ddic_type = 2. CASE sy-subrc. WHEN 1. RAISE type_not_found. WHEN 2. RAISE no_ddic_type. ENDCASE. NEW-LINE. LOOP AT lt_flist ASSIGNING . WRITE -reptext(-outputlen) COLOR COL_HEADING. ENDLOOP. ULINE. ENDMETHOD. Executable Program BC402_DYS_RTTI_HEADERS REPORT
bc402_dys_rtti_headers MESSAGE-ID bc402.
TYPE-POOLS: abap. DATA: gt_cust gt_conn
TYPE ty_customers, TYPE ty_connections.
DATA: gv_tabname
TYPE string.
FIELD-SYMBOLS:
© Copyright . All rights reserved.
523
Unit 11: Dynamic Programming
TYPE ANY TABLE. SELECTION-SCREEN COMMENT 1(80) text-sel. PARAMETERS: pa_xconn TYPE xfeld RADIOBUTTON GROUP tab DEFAULT 'X', pa_xcust TYPE xfeld RADIOBUTTON GROUP tab . PARAMETERS: pa_nol TYPE i DEFAULT '100'. START-OF-SELECTION. * specific part *----------------------------------------------------* CASE 'X'. WHEN pa_xconn. gv_tabname = 'SPFLI'. ASSIGN gt_conn TO . WHEN pa_xcust. gv_tabname = 'SCUSTOM'. ASSIGN gt_cust TO . ENDCASE. * dynamic part *------------------------------------------------------* TRY.
SELECT * FROM (gv_tabname) INTO TABLE UP TO pa_nol ROWS. CATCH cx_sy_dynamic_osql_error. MESSAGE e061. ENDTRY. CALL METHOD cl_bc402_dys_rtti_headers=>write_headers EXPORTING iv_tabname = gv_tabname EXCEPTIONS type_not_found = 1 no_structure = 2 no_ddic_type = 3. CASE sy-subrc. WHEN 1. MESSAGE e050 WITH gv_tabname. WHEN 2. MESSAGE e051 WITH gv_tabname. WHEN 3. MESSAGE e052 WITH gv_tabname. ENDCASE. cl_bc402_dys_gen_types=>write_any_table( ).
524
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
Object Type Analysis
Figure 206: Analysis of an Object Type
RTTI permits you to analyze the attributes of objects. Perform analysis by using classes CL_ABAP_CLASSDESCR and CL_ABAP_INTFDESCR. Most of the attributes and methods for these two classes are defined in the (abstract) shared superclass CL_ABAP_OBJECTDESCR because they are required to analyze classes and interfaces.
Note: A class is analyzed in the example shown in the figure. Most of the information also applies to the analysis of interfaces. Class CL_ABAP_CLASSDESCR contains public attributes that list the attributes, methods, events, interfaces, and other objects of the described class. Internal tables in the system contain these public attributes. Some of these attributes, such as METHODS, are defined as nested internal tables in which each line itself contains one or more internal tables. For example, these nested internal tables contain lists with parameters and exceptions for the respective method. In addition to these inherited attributes, class CL_ABAP_CLASSDESCR also provides specific attributes, such as the CLASS_KIND attribute, which you use to determine whether the class was flagged as abstract, final, and so on.
© Copyright . All rights reserved.
525
Unit 11: Dynamic Programming
Note: Class CL_ABAP_INTFDESCR contains an INTF_KIND attribute instead, which you use to determine whether an interface is comprised of multiple interfaces. The figure demonstrates how to use RTTI to determine all the parameters of the constructor for class CL_RENTAL. After the system generates the description object and performs the down cast, it reads the description of the constructor method from the list of methods (statement with READ TABLE). The system then evaluates the list of parameters for the constructor method in a loop (LOOP over the inner internal table). The description classes for object types also provide navigation methods for determining the details of a used type. For example, the GET_ATTRIBUTE_TYPE method returns the description object for the type of a specific attribute, while GET_METHOD_PARAMETER_TYPE analyzes the type of a specific method parameter, and so on. The GET_SUPER_CLASS_TYPE method is specific to classes. It returns the description object for the direct superclass, if any.
526
© Copyright . All rights reserved.
Lesson: Describing Data Types, Data Objects, and Objects at Runtime
LESSON SUMMARY You should now be able to: ●
Explain the principle of RTTI
●
Describe data types and data objects at runtime
●
Describe object types and objects at runtime
© Copyright . All rights reserved.
527
Unit 11 Lesson 3 Creating Data Types, Data Objects, and Objects at Runtime
LESSON OVERVIEW This lesson discusses the method for generating objects, that is, instances of classes, at runtime from object-oriented programming. It discusses a similar method for generating data objects as instances of data types at runtime. The lesson also discusses runtime type creation (RTTC), a technique that enables you to define the data type at runtime. Business Example You need to develop a flexible application. In addition to accessing existing data objects dynamically and analyzing the underlying data types, you also want to learn about the techniques available to generate objects, data objects, and data types at runtime according to the requirements of program. For this reason, you require the following knowledge: ●
An understanding of how to generate objects or instances at runtime
●
An understanding of how to generate data objects at runtime
●
An understanding of how to generate data types at runtime
LESSON OBJECTIVES After completing this lesson, you will be able to:
528
●
Create objects (instances) at runtime
●
Create data objects at runtime
●
Create data types at runtime
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
Dynamic Object Creation
Figure 207: Options for Generating Objects at Runtime
The CREATE OBJECT statement generates objects or specifically, instances of classes at runtime. Define the type of object, that is, the class to be instantiated implicitly through the static type of the reference variable used. Alternatively, use the TYPE addition to specify the class to be instantiated in the CREATE OBJECT statement. Apply the following rules while using the CREATE OBJECT statement: A class, not an interface, must appear after the TYPE addition.
●
●
You must be able to instantiate the class, which means that it cannot be flagged as abstract.
●
The static type of the reference variable must be compatible with the class.
The last rule applies because the system carries out an implicit up cast if necessary when you specify the type explicitly. The reference variable can become an object if it meets one of the following conditions: ● The reference variable is typed with the class to be instantiated. ●
●
●
The reference variable is typed with a superclass of the class to be instantiated. The reference variable is typed with an interface that is implemented by the class to be instantiated. The reference variable is typed with generic type REF TO OBJECT type.
The syntax for specifying an explicit type can include a data object in parentheses after TYPE. This syntax enables dynamic selection of the class to be instantiated.
© Copyright . All rights reserved.
529
Unit 11: Dynamic Programming
Hint: If classes are available for selections that are not linked through a shared superclass or the same implementing interface, type the reference variable completely generically with TYPE REF TO OBJECT.
Dynamic Passing of Parameters
Figure 208: Dynamic Passing of Parameters
If all potential classes have the same constructor signature, provide the parameters with data statically. However, it is likely that the parameters and exceptions of the constructors will differ. In this case, you need to use dynamic parameter transfer. Like with dynamic method calls, perform dynamic parameter transfer using internal tables after the PARAMETER-TABLE and EXCEPTION-TABLE additions. Enter these tables and fill them as you do for method calls.
530
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
Dynamic Data Object Creation
Figure 209: Options for Creating Data Objects at Runtime
You can also create data objects at runtime. The corresponding statement, CREATE DATA, has a similar definition to that of the CREATE OBJECT statement. The CREATE DATA statement creates a data object dynamically, assigns memory to it, and points the general data reference variable to that data object in memory. The data object is not given a name, so it is often called an anonymous data object. To address the data object, dereference the reference variable at runtime.
Hint: In contrast to the static DATA declaration, the system does not reserve the memory for the data objects until runtime, and it does not reserve the memory when the respective program is loaded. Like with class instances, the garbage collector releases the memory again as soon as the program deletes the last reference to the data object. Use CREATE DATA to define the type of the data object implicitly by using the type of the reference variable, or explicitly by using the TYPE addition. To use a number of variants that you are familiar with, use explicit typing. These variants can be from DATA declarations, such as the use of built-in types, the implicit construction of table types, and the reference to an existing data object with LIKE. To define the data type for the generated data objects dynamically, use character-type data objects in parentheses.
© Copyright . All rights reserved.
531
Unit 11: Dynamic Programming
Note: Alternatively, use the TYPE HANDLE addition to refer to a type description object from the RTTI.
Access to Dynamically Created Data Objects
Figure 210: Access to Dynamically Created Data Objects
If the system determines the data type dynamically, type the reference variable generically with TYPE REF TO DATA. This is the only generic type that supports data references at present. You assign a field symbol to the references data object for the following reasons: ●
You can only dereference the generic data reference in the ASSIGN statement.
●
You can use generically typed field symbols anywhere.
Hint: If the new data object is an internal table and you want to use it in the corresponding operand positions, the field symbol must contain at least type ANY TABLE.
532
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
Dynamically Generated Internal Table and Dynamic SELECT
Figure 211: Example – Dynamically Generated Internal Table and Dynamic SELECT
The figure shows an example of a dynamic database access in which the suitable data object is generated at runtime.
© Copyright . All rights reserved.
533
Unit 11: Dynamic Programming
534
© Copyright . All rights reserved.
Unit 11 Exercise 29 Create Data Objects at Runtime
Business Example You need to develop a simple program that displays the contents of any database table by using the options available in dynamic programming. Generate and use data objects at runtime, and use generically typed reference variables. Task 1 Copy program BC402_DYS_RTTI_HEADERS or your own program, ZBC402_##_RTTI_HEADERS and name it ZBC402_##_CREATE_DATA, where ## is your group number. Familiarize yourself with the program and how it works.
Hint: If you have not performed the exercise on RTTI, simply copy program ZBC402_##_GEN_DATA. The display of the column headers is not relevant to this exercise. 1. Copy the program and all its subcomponents. 2. Activate and test the program. Analyze the source code. Which data objects are filled during the database access? Which types do they have? Were they created statically or dynamically?
Task 2 Replace the two statically defined internal tables with a data object that you generate after the CASE structure (standard table with non-unique standard key). Define the type of the data object dynamically to ensure that the line type precisely matches the structure of the database table you want to read. 1. Define a generically typed data reference (suggested name is gr_data). 2. Use the gr_data data reference to generate an internal table immediately after the ENDCASE statement. Access the contents of data object gv_tabname to define the line type of the table dynamically. 3. Move one of the ASSIGN statements outside the WHEN blocks after the data object is generated, and delete the other ASSIGN statement. Replace the statically defined internal table with the dynamically generated table.
© Copyright . All rights reserved.
535
Unit 11: Dynamic Programming
Hint: Dereference the generic data reference.
4. Why can you not continue to use gr_data directly? 5. Delete the definitions of the two static internal tables or flag them as comments. 6. Activate and test your program.
Task 3 The static part of the program now contains only the filling of data object gv_tabname with an appropriate literal for the name of the database table. Replace both checkboxes on the selection screen with a parameter for the name of any database table. 1. Delete the definitions parameters of the two checkboxes or flag them as comments. Copy the user entry from the parameter directly to data object gv_tabname instead of evaluating the checkboxes in a CASE structure. 2. Create a new parameter (suggested name is pa_tab). Hint: If you use the global type dd02l-tabname, provide a value (F4) help function for the users. 3. Delete the CASE structure or flag it as comments. In the same position, program a value assignment from pa_tab to gv_tabname. 4. Activate and test your program.
536
© Copyright . All rights reserved.
Unit 11 Solution 29 Create Data Objects at Runtime
Business Example You need to develop a simple program that displays the contents of any database table by using the options available in dynamic programming. Generate and use data objects at runtime, and use generically typed reference variables. Task 1 Copy program BC402_DYS_RTTI_HEADERS or your own program, ZBC402_##_RTTI_HEADERS and name it ZBC402_##_CREATE_DATA, where ## is your group number. Familiarize yourself with the program and how it works.
Hint: If you have not performed the exercise on RTTI, simply copy program ZBC402_##_GEN_DATA. The display of the column headers is not relevant to this exercise. 1. Copy the program and all its subcomponents. a) Perform this step as usual. 2. Activate and test the program. Analyze the source code. Which data objects are filled during the database access? Which types do they have? Were they created statically or dynamically? a) One of two internal tables, gt_conn or gt_cust, is filled depending on the user entry. While the data object assigned to field symbol (which is therefore addressed in the SELECT statement) is determined dynamically, the data objects themselves have static definitions (DATA statement).
Task 2 Replace the two statically defined internal tables with a data object that you generate after the CASE structure (standard table with non-unique standard key). Define the type of the data object dynamically to ensure that the line type precisely matches the structure of the database table you want to read. 1. Define a generically typed data reference (suggested name is gr_data). a) See the source code excerpt from the model solution.
© Copyright . All rights reserved.
537
Unit 11: Dynamic Programming
2. Use the gr_data data reference to generate an internal table immediately after the ENDCASE statement. Access the contents of data object gv_tabname to define the line type of the table dynamically. a) See the source code excerpt from the model solution. 3. Move one of the ASSIGN statements outside the WHEN blocks after the data object is generated, and delete the other ASSIGN statement. Replace the statically defined internal table with the dynamically generated table. Hint: Dereference the generic data reference.
a) See the source code excerpt from the model solution. 4. Why can you not continue to use gr_data directly? a) Because gr_data has a generic type and ABAP only allows dereferenced access to generically typed data references in ASSIGN statements. 5. Delete the definitions of the two static internal tables or flag them as comments. a) See the source code excerpt from the model solution. 6. Activate and test your program. a) Perform this step as usual.
Task 3 The static part of the program now contains only the filling of data object gv_tabname with an appropriate literal for the name of the database table. Replace both checkboxes on the selection screen with a parameter for the name of any database table. 1. Delete the definitions parameters of the two checkboxes or flag them as comments. Copy the user entry from the parameter directly to data object gv_tabname instead of evaluating the checkboxes in a CASE structure. a) See the source code excerpt from the model solution. 2. Create a new parameter (suggested name is pa_tab). Hint: If you use the global type dd02l-tabname, provide a value (F4) help function for the users. a) See the source code excerpt from the model solution. 3. Delete the CASE structure or flag it as comments. In the same position, program a value assignment from pa_tab to gv_tabname. a) See the source code excerpt from the model solution.
538
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
4. Activate and test your program. a) Perform this step as usual. *&--------------------------------------* *& Report BC402_DYS_CREATE_DATA *& *&--------------------------------------* *& *& *&--------------------------------------* REPORT bc402_dys_create_data MESSAGE-ID bc402. *DATA: * gt_cust TYPE ty_customers, * gt_conn TYPE ty_connections. DATA: gr_data TYPE REF TO data. DATA: gv_tabname TYPE string. FIELD-SYMBOLS: TYPE ANY TABLE. SELECTION-SCREEN COMMENT 1(80) text-sel. *PARAMETERS: * pa_xconn TYPE xfeld RADIOBUTTON GROUP tab DEFAULT 'X', * pa_xcust TYPE xfeld RADIOBUTTON GROUP tab . PARAMETERS pa_tab TYPE dd02l-tabname DEFAULT 'SPFLI'. PARAMETERS: pa_nol TYPE i DEFAULT '100'. START-OF-SELECTION. * specific part *---------------------------------* * CASE 'X'. * WHEN pa_xconn. * * gv_tabname = 'SPFLI'. * ASSIGN gt_conn TO . * * WHEN pa_xcust. * * gv_tabname = 'SCUSTOM'. * ASSIGN gt_cust TO . * * ENDCASE. * dynamic part *---------------------------------* gv_tabname = pa_tab. CREATE DATA gr_data TYPE TABLE OF (gv_tabname). ASSIGN gr_data->* TO . TRY.
© Copyright . All rights reserved.
539
Unit 11: Dynamic Programming
SELECT * FROM (gv_tabname) INTO TABLE UP TO pa_nol ROWS. CATCH cx_sy_dynamic_osql_error. MESSAGE e061. ENDTRY. CALL METHOD cl_bc402_dys_rtti_headers=>write_headers EXPORTING iv_tabname = gv_tabname EXCEPTIONS type_not_found = 1 no_structure = 2 no_ddic_type = 3. CASE sy-subrc. WHEN 1. MESSAGE e050 WITH gv_tabname. WHEN 2. MESSAGE e051 WITH gv_tabname. WHEN 3. MESSAGE e052 WITH gv_tabname. ENDCASE. cl_bc402_dys_gen_types=>write_any_table( ).
540
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
Runtime Type Creation (RTTC)
Figure 212: Dynamic Type Creation Methods of Runtime Type Services
RTTI enables you to describe data types and object types with instances of RTTI classes or type description objects. The RTTI concept was enhanced in SAP Web AS 6.40. In addition to describing existing types, you use it to generate new types. This enhanced function set is called runtime type creation (RTTC). RTTC consists of a number of additional static methods in the RTTI description classes.
Hint: Note that type generation is restricted to data types. You cannot generate classes or interfaces dynamically. In the figure, the CL_ABAP_REFDESCR, CL_ABAP_STRUCTDESCR, and CL_ABAP_TABLEDESCR classes are enhanced with a CREATE method, while the CL_ABAP_ELEMDESCR class receives an appropriate GET method for each built-in elementary ABAP type such as, GET_I, GET_F, GET_C, GET_STRING. These methods return pointers to an instance of the respective class. In contrast to the DESCRIBE methods of the root class, the attribute values of this instance do not come from analyzing a data object, a reference, or a named type. Instead, they are passed on to the RTTC method explicitly. The method signatures have been designed accordingly. While the GET_I method does not need any other input (type i is complete), method GET_P has two import parameters defined: one for length and the other for the number of decimal places.
© Copyright . All rights reserved.
541
Unit 11: Dynamic Programming
The CREATE method for reference types expects the pointer to the description object for the referenced type, while the CREATE method for structure types expects a list with names and types of the components. When table types are generated, a reference to an RTTI object that describes the line type is expected (among other things).
Dynamic Table Type Creation
Figure 213: RTTC – Creating a Table Type
The figure shows how to generate a table type dynamically with RTTC. You are required to specify only the P_LINE_TYPE parameter for the CREATE method. The parameter is of type REF TO CL_ABAP_DATADESCR and needs to be supplied with a reference to any description object for a data type. In the example shown in the figure, SPFLI is used as the line type. The DESCRIBE_BY_NAME method returns the matching description object. The optional parameters are used to define the table type and key. If you do not specify them, the system uses a standard table with a non-unique standard key.
542
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
Usage of a Dynamically Created Data Type
Figure 214: Generating an Internal Table with a Dynamically Created Type
To dynamically create a data object with this specific type, use the dynamically generated type in the CREATE DATA statement. Use the HANDLE addition with the CREATE DATA statement to generate a data object whose type matches the specified type description object. Specify the HANDLE as a reference variable with static type CL_ABAP_DATADESCR or one of its subclasses. The system may have created the object based on the existing data types by using RTTI methods or by dynamically defining a new data type.
© Copyright . All rights reserved.
543
Unit 11: Dynamic Programming
544
© Copyright . All rights reserved.
Unit 11 Exercise 30 Create Data Types at Runtime with Runtime Type Creation (RTTC)
Business Example You have developed a simple program that displays the contents of any database table. The program now needs to allow users to select the specific columns they want to read and display. You need to use function module BC402_SELECT_COMPONENTS, which displays all the components of a global structure type and enables users to select components. Therefore, you need to use the options of runtime type creation (RTTC) to generate a table type dynamically. The table type should only contain the user-selected components in its lines. Use RTTC to generate structure types and table types at runtime, and generate data objects based on dynamic data types. Task 1 Display function module BC402_SELECT_COMPONENTS. Analyze the interface and test the functional scope of the function module. 1. Display the function module. Analyze the interface. Which parameters are there and what are their types? 2. Which exceptions can the function module raise, and what purpose do they serve? 3. Test the function module.
Task 2 Copy program BC402_DYS_CREATE_DATA or your own program ZBC402_##_CREATE_DATA and name it ZBC402_##_RTTC, where ## is your group number. Familiarize yourself with the program and how it works. Implement a call of the function module before the dynamic generation of the data object. Pass the table name that the user entered on the selection screen to the import parameter. 1. Copy the program and all its subcomponents. 2. Call the function module before the CREATE DATA statement. Create a suitably typed data object to supply the export parameter with data. Pass the contents of gv_tabname to the import parameter. React to exceptions with suitable error messages from message class BC402.
© Copyright . All rights reserved.
545
Unit 11: Dynamic Programming
Task 3 Copy template CL_BC402_DYT_RTTC and name it ZCL_BC402_##_RTTC, where ## is your group number. Familiarize yourself with the signature of method create_table_type. 1. Copy the global class. 2. Analyze the create_table_type method signature. Which parameters are defined? How are they typed?
Task 4 Implement the create_table_type method. Use the RTTI techniques to analyze the data type of which the name is contained in the import parameter. Use a suitable navigation method to calculate a list with the names and RTTI type description objects for all components in the structure. 1. Call a suitable method of class CL_ABAP_TYPEDESCR to generate a type description object for the data type. Create a reference variable with a suitable type for the return value (suggested name: lo_struct). Hint: For simplicity, assume that the data type is a structure type in the ABAP Dictionary and perform a direct down cast to the corresponding reference variable. 2. Call the get_components method for the RTTI instance. Create a data object with a suitable type for the return value (suggested name is lt_comps).
Task 5 Change the list of components so that it only contains the components listed in import parameter it_comp_names. Based on this list of components, create a new structure type, and then a new table type. 1. Implement a loop over the lt_comps component list. 2. Check whether the component name in each line is contained in import parameter it_comp_names. Hint: Use a statement such as FIND ... IN TABLE or READ TABLE ... TRANSPORTING NO FIELDS. 3. Remove the current line from lt_comps if the corresponding table name is not contained in import parameter it_comp_names.
546
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
Hint: Use the abbreviated syntax for index access in loops here.
4. To generate an RTTI type description object for a new structure type, call the CREATE method of class CL_ABAP_STRUCTDESCR. Pass the reduced component list to the method. Create a data object with a suitable type for the return parameter (suggested name: lo_struct_new). 5. To generate an RTTI type description object for a new table type, call the CREATE method of class CL_ABAP_TABLEDESCR. Pass the reference to the RTTI object for the new structure type. Leave all the optional parameters set to their default values. Transfer the result of the method call directly to return parameter ro_table_def of method create_table_type.
Task 6 Go back to your executable program ZBC402_##_RTTC. Call method create_table_type to generate a table type according to the requirements of the user. Use a new data type when you generate the data object dynamically. Change the SELECT statement so that it reads only those fields from the database that are contained in the line type of the internal table.
Hint: Method write_headers still outputs the headers for all the columns in the table. You either work without the headers completely or use method write_headers_by_data from class CL_BC402_DYS_RTTI_HEADERS. This method analyzes the actual line type of an internal table and outputs the column headers for it. 1. Call method create_table_type in the program directly after the call of function module BC402_SELECT_COMPONENTS. Pass the name of the database table and the list of components that the user selected to the method create_table_type. 2. Change the type in the CREATE DATA statement. Use the TYPE HANDLE addition to use the newly generated table type. 3. Change the SELECT statement. Use the list of component names as a dynamic field list. Hint: Alternatively, use the INTO CORRESPONDING FIELDS OF TABLE addition.
4. Activate and test your program.
© Copyright . All rights reserved.
547
Unit 11 Solution 30 Create Data Types at Runtime with Runtime Type Creation (RTTC)
Business Example You have developed a simple program that displays the contents of any database table. The program now needs to allow users to select the specific columns they want to read and display. You need to use function module BC402_SELECT_COMPONENTS, which displays all the components of a global structure type and enables users to select components. Therefore, you need to use the options of runtime type creation (RTTC) to generate a table type dynamically. The table type should only contain the user-selected components in its lines. Use RTTC to generate structure types and table types at runtime, and generate data objects based on dynamic data types. Task 1 Display function module BC402_SELECT_COMPONENTS. Analyze the interface and test the functional scope of the function module. 1. Display the function module. Analyze the interface. Which parameters are there and what are their types? a) There is one import parameter, iv_tabname, with type csequence and one export parameter, et_comp_names, with type string_table (standard table with string line type). 2. Which exceptions can the function module raise, and what purpose do they serve? a) The exceptions raised by the function module and the purposes served by those exceptions are as follows: ●
TYPE_NOT_FOUND The passed on type is unknown.
●
NO_STRUCTURE The passed on type is not a structure.
●
NO_DDIC_TYPE The passed on type is not a DDIC type.
3. Test the function module. a) Perform this step as usual.
Task 2
548
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
Copy program BC402_DYS_CREATE_DATA or your own program ZBC402_##_CREATE_DATA and name it ZBC402_##_RTTC, where ## is your group number. Familiarize yourself with the program and how it works. Implement a call of the function module before the dynamic generation of the data object. Pass the table name that the user entered on the selection screen to the import parameter. 1. Copy the program and all its subcomponents. a) Perform this step as usual. 2. Call the function module before the CREATE DATA statement. Create a suitably typed data object to supply the export parameter with data. Pass the contents of gv_tabname to the import parameter. React to exceptions with suitable error messages from message class BC402. a) See the source code excerpt from the model solution.
Task 3 Copy template CL_BC402_DYT_RTTC and name it ZCL_BC402_##_RTTC, where ## is your group number. Familiarize yourself with the signature of method create_table_type. 1. Copy the global class. a) Perform this step as usual. 2. Analyze the create_table_type method signature. Which parameters are defined? How are they typed? a) Import parameter iv_tabname with generic type csequence, import parameter it_comp_names with type string_table, and return parameter ro_tabledescr, a reference to class cl_abap_tabledescr.
Task 4 Implement the create_table_type method. Use the RTTI techniques to analyze the data type of which the name is contained in the import parameter. Use a suitable navigation method to calculate a list with the names and RTTI type description objects for all components in the structure. 1. Call a suitable method of class CL_ABAP_TYPEDESCR to generate a type description object for the data type. Create a reference variable with a suitable type for the return value (suggested name: lo_struct). Hint: For simplicity, assume that the data type is a structure type in the ABAP Dictionary and perform a direct down cast to the corresponding reference variable. a) See the source code excerpt from the model solution.
© Copyright . All rights reserved.
549
Unit 11: Dynamic Programming
2. Call the get_components method for the RTTI instance. Create a data object with a suitable type for the return value (suggested name is lt_comps). a) See the source code excerpt from the model solution.
Task 5 Change the list of components so that it only contains the components listed in import parameter it_comp_names. Based on this list of components, create a new structure type, and then a new table type. 1. Implement a loop over the lt_comps component list. a) See the source code excerpt from the model solution. 2. Check whether the component name in each line is contained in import parameter it_comp_names. Hint: Use a statement such as FIND ... IN TABLE or READ TABLE ... TRANSPORTING NO FIELDS. a) See the source code excerpt from the model solution. 3. Remove the current line from lt_comps if the corresponding table name is not contained in import parameter it_comp_names. Hint: Use the abbreviated syntax for index access in loops here.
a) See the source code excerpt from the model solution. 4. To generate an RTTI type description object for a new structure type, call the CREATE method of class CL_ABAP_STRUCTDESCR. Pass the reduced component list to the method. Create a data object with a suitable type for the return parameter (suggested name: lo_struct_new). a) See the source code excerpt from the model solution. 5. To generate an RTTI type description object for a new table type, call the CREATE method of class CL_ABAP_TABLEDESCR. Pass the reference to the RTTI object for the new structure type. Leave all the optional parameters set to their default values. Transfer the result of the method call directly to return parameter ro_table_def of method create_table_type. a) See the source code excerpt from the model solution.
Task 6 Go back to your executable program ZBC402_##_RTTC. Call method create_table_type to generate a table type according to the requirements of the user. Use a new data type when you generate the data object dynamically.
550
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
Change the SELECT statement so that it reads only those fields from the database that are contained in the line type of the internal table.
Hint: Method write_headers still outputs the headers for all the columns in the table. You either work without the headers completely or use method write_headers_by_data from class CL_BC402_DYS_RTTI_HEADERS. This method analyzes the actual line type of an internal table and outputs the column headers for it. 1. Call method create_table_type in the program directly after the call of function module BC402_SELECT_COMPONENTS. Pass the name of the database table and the list of components that the user selected to the method create_table_type. a) See the source code excerpt from the model solution. 2. Change the type in the CREATE DATA statement. Use the TYPE HANDLE addition to use the newly generated table type. a) See the source code excerpt from the model solution. 3. Change the SELECT statement. Use the list of component names as a dynamic field list. Hint: Alternatively, use the INTO CORRESPONDING FIELDS OF TABLE addition.
4. Activate and test your program. a) Perform this step as usual. Method create_table_type (Class CL_BC402_DYS_RTTC) METHOD create_table_type. DATA: lo_struct TYPE REF TO cl_abap_structdescr, lo_struct_new TYPE REF TO cl_abap_structdescr. DATA: lt_comps TYPE cl_abap_structdescr=>component_table. FIELD-SYMBOLS: LIKE LINE OF lt_comps. * get description of transparent table (=structure type) lo_struct ?= cl_abap_typedescr=>describe_by_name( iv_tabname ). * get list of components (including component types) lt_comps = lo_struct->get_components( ). LOOP AT lt_comps ASSIGNING .
© Copyright . All rights reserved.
551
Unit 11: Dynamic Programming
FIND -name IN TABLE it_comp_names. IF sy-subrc 0. DELETE lt_comps. ENDIF. ENDLOOP. * alternatve solution with read table * remove all components but the requested ones * LOOP AT lt_comps ASSIGNING . * READ TABLE it_comp_names * TRANSPORTING NO FIELDS * WITH TABLE KEY table_line = -name. * IF sy-subrc 0. * DELETE lt_comps . * ENDIF. * * ENDLOOP. * create new structure type with the remaining components lo_struct_new = cl_abap_structdescr=>create( p_components = lt_comps ). * create table type with this new structure type as line type ro_tabledescr = cl_abap_tabledescr=>create( p_line_type = lo_struct_new ). ENDMETHOD. Executable Program BC402_DYS_RTTC REPORT
bc402_dys_rttc MESSAGE-ID bc402.
DATA: gr_table
TYPE REF TO data.
DATA: gv_tabname TYPE string. DATA: gt_comp_names TYPE string_table, go_table TYPE REF TO cl_abap_tabledescr. FIELD-SYMBOLS: TYPE ANY TABLE. SELECTION-SCREEN COMMENT 1(80) text-sel. PARAMETERS pa_tab TYPE dd02l-tabname DEFAULT 'SPFLI'. PARAMETERS: pa_nol TYPE i DEFAULT '100'. START-OF-SELECTION. gv_tabname = pa_tab. CALL FUNCTION 'BC402_SELECT_COMPONENTS' EXPORTING iv_tabname = gv_tabname
552
© Copyright . All rights reserved.
Lesson: Creating Data Types, Data Objects, and Objects at Runtime
IMPORTING et_comp_names EXCEPTIONS type_not_found no_structure no_ddic_type
= gt_comp_names = 1 = 2 = 3.
CASE sy-subrc. WHEN 1. MESSAGE e050 WITH gv_tabname. WHEN 2. MESSAGE e051 WITH gv_tabname. WHEN 3. MESSAGE e052 WITH gv_tabname. ENDCASE. go_table = cl_bc402_dys_rttc=>create_table_type( iv_tabname = gv_tabname it_comp_names = gt_comp_names ). CREATE DATA gr_table TYPE HANDLE go_table. ASSIGN gr_table->* TO . TRY.
SELECT (gt_comp_names) FROM (gv_tabname) INTO TABLE UP TO pa_nol ROWS. CATCH cx_sy_dynamic_osql_error. MESSAGE e061. ENDTRY. CALL METHOD cl_bc402_dys_rtti_headers=>write_headers_by_data EXPORTING it_table = EXCEPTIONS no_structure = 1 no_ddic_type = 2 component_not_elem = 3. CASE sy-subrc. WHEN 1. MESSAGE e050 WITH gv_tabname. WHEN 2. MESSAGE e051 WITH gv_tabname. WHEN 3. MESSAGE e053 WITH gv_tabname. ENDCASE. cl_bc402_dys_gen_types=>write_any_table( ).
© Copyright . All rights reserved.
553
Unit 11: Dynamic Programming
LESSON SUMMARY You should now be able to:
554
●
Create objects (instances) at runtime
●
Create data objects at runtime
●
Create data types at runtime
© Copyright . All rights reserved.
Unit 11 Learning Assessment
1. The INDEX TABLE is a special generic data type that is only compatible with internal tables. Determine whether this statement is true or false. X
True
X
False
2. Field symbols are pointers that you assign to data objects statically. Determine whether this statement is true or false. X
True
X
False
3. You can replace data objects in operand positions directly by character-type data objects in parentheses by using the ASSIGN statement for the data object to which you need to assign the field symbol. Determine whether this statement is true or false. X
True
X
False
4. When you assign values between two reference variables with different types, you perform what is called a “cast assignment”. Determine whether this statement is true or false. X
True
X
False
© Copyright . All rights reserved.
555
Unit 11: Learning Assessment
5. Which of the following classes do you instantiate and use to describe specific types? Choose the correct answers. X
A CL_ABAP_ELEMDESCR
X
B CL_ABAP_INTFDESCR
X
C CL_ABAP_STRUCTDESCR
X
D CL_ABAP_RTTI
6. The description classes for object types provide navigation methods for determining the details of a used type. Determine whether this statement is true or false. X
True
X
False
7. To generate objects at runtime, the static type of the reference variable must be compatible with the class. Determine whether this statement is true or false. X
True
X
False
8. If you use character-type data objects in parentheses, you can also define the data type for generated data objects dynamically. Determine whether this statement is true or false. X
True
X
False
9. With the HANDLE addition, the CREATE DATA statement creates a data object whose data type is described by an RTTS type object. Determine whether this statement is true or false.
556
X
True
X
False
© Copyright . All rights reserved.
Unit 11 Learning Assessment - Answers
1. The INDEX TABLE is a special generic data type that is only compatible with internal tables. Determine whether this statement is true or false. X
True
X
False
2. Field symbols are pointers that you assign to data objects statically. Determine whether this statement is true or false. X
True
X
False
3. You can replace data objects in operand positions directly by character-type data objects in parentheses by using the ASSIGN statement for the data object to which you need to assign the field symbol. Determine whether this statement is true or false. X
True
X
False
4. When you assign values between two reference variables with different types, you perform what is called a “cast assignment”. Determine whether this statement is true or false. X
True
X
False
© Copyright . All rights reserved.
557
Unit 11: Learning Assessment - Answers
5. Which of the following classes do you instantiate and use to describe specific types? Choose the correct answers. X
A CL_ABAP_ELEMDESCR
X
B CL_ABAP_INTFDESCR
X
C CL_ABAP_STRUCTDESCR
X
D CL_ABAP_RTTI
6. The description classes for object types provide navigation methods for determining the details of a used type. Determine whether this statement is true or false. X
True
X
False
7. To generate objects at runtime, the static type of the reference variable must be compatible with the class. Determine whether this statement is true or false. X
True
X
False
8. If you use character-type data objects in parentheses, you can also define the data type for generated data objects dynamically. Determine whether this statement is true or false. X
True
X
False
9. With the HANDLE addition, the CREATE DATA statement creates a data object whose data type is described by an RTTS type object. Determine whether this statement is true or false.
558
X
True
X
False
© Copyright . All rights reserved.
View more...
Comments