Você está na página 1de 82

MASTER DE SAP

TAW10_3

1
Unidad 1: INTRODUCTIÓN A
OBJECT-ORIENTED
Modelo de programación orietada a objetos

Cambio de Procedural a Programación Orientada a Objetos


Los objetos ABAP unen elementos de programación orientada a objetos y del modelo
procedural. En su desarrollo, solo se aplicaron los conceptos de POO que estaban
probados como válidos de otros lenguajes y se introdujeron otros conceptos ventajosos
propios.

Características del modelo procedural:


• Los datos y las funciones se mantienen separados.
• Por lo general no se encapsula el acceso a datos.
• Posibilidad de encapsular funciones usando modularización.

En el modelo procedural se separa datos de funciones. No se realiza un acceso


encapsulado a los datos pero posibilita encapsular funciones usando modularización.
Cada programa puede acceder a cada variable. Esto significa que el modelo de
programación no soporta el acceso consistente a algunas partes de los datos. Cada
vez que se llama a un function module en un main program, su function group es
cargado en la sesión interna y permanece activo hasta que el main program acaba. El
main y los function groups que fueron llamados en el, son guardados en diferentes áreas
de memoria. Incluso si sus data objects tienen los mismos nombres, no se comparten.
No es posible acceder a los datos globales de los function group desde el main
program.

La encapsulación incorpora la idea que la implementación de un servicio puede ser


escondida a los otros componentes del sistema.

Un function group es una unidad de datos y funciones que gestiona esos datos. El
acceso encapsulado a datos y servicios puede ser soportado en la parte procedural de
ABAP objects. Esto significa que las BAPIs podrían ser implementadas como function
modules y los Business Objects podrían ser implementados como function groups.

La posibilidad de crear varias instancias en ejecución en una capsula para cada


programa es una de las características clave de la POO. A diferencia del modelo
procedural, el uso de instanciación múltiple en la POO permite crear una abstracción
directa de un objeto real.

ABAP Objects en POO


ABAP Objects no es un nuevo lenguaje, pero ha sido diseñado como una extensión
sistemática de ABAP. Todas las extensiones, incluyendo las viejas partes de
procedural, son compatibles. Los type checks son más estrictos que en el modelo
procedural. Las sentencias obsoletas son prohibidas y llevan a error (aunque no es
posible completamente prevenir su uso debido a la compatibilidad de las extensiones).
Encontramos una lista de elementos obsoletos en la ABAP keyword documentation.

2
Los objetos se comportan como sistemas cliente/servidor. Cuando un objeto envía
mensajes a otro objetos, el primer objeto puede ser un cliente y el el otro un servidor. En
principio, los objetos pueden interpretar ambos roles simultáneamente. En POO, los
servicios son distribuidos por los objetos para evitar redundancias y así cada objeto
ofrece exactamente los servicios que están en su área de responsabilidad. Si un objeto
necesita otros servicios, los pide a otros objetos (principio de delegación).

Componentes adicionales:
• Herencia: Consiste en que una clase (subclase) adopta la estructura y
comportamiento de otra clase (superclase), adaptándola y extendiéndola.
• Polimorfismo: Consiste en que instancias de diferentes clases responden de
manera diferente a los mismos mensajes.
• Event control: Los objetos pueden lanzar eventos también. Son mandados
cuando en el momento de desarrollo no se conoce todavía como van a reaccionar
los objetos.

Ventajas de POO:
• Mejor estructura de software y consistencia en el proceso de desarrollo.
• Reduce el esfuerzo de mantenimiento y disminuye la susceptibilidad de
errores.
• Mejor la integración del usuario en el analisis, diseño, y proceso de
mantenimiento.
• Las opciones de extensión del software son más simples y seguras.

Análisis y diseño con UML

Clasificación
Clase es una descripción de un conjunto de objetos con las mismas características y
el mismo comportamiento.

Un objeto es una instancia de su clase. Tiene una identidad, un status y un


comportamiento (behavior). Identidad es un atributo que distingue cada objeto de otros
objetos de la misma clase. Dos objetos diferentes pueden tener idénticos los valores
de sus atributos y no ser idénticos.

Comparación de clases y objetos:


• Clase:
o Descripción general de los objetos.
o Especificar el estatus de los datos (atributos) y el comportamiento
(métodos).
• Objeto:
o Representación de una parte del mundo real.
o Forma/espécimen/instancia concreta de una clase.

Modelando en UML
UML es un lenguaje global estándar. Es usado para especificación, construcción,
visualización y documentación de modelos de sistemas de software y permitir una
comunicación uniforme entres los usuarios.

3
Describe diferentes diagramas para representar varias vistas de un sistema:
• Class diagrams (Diagrama de clases): Muestra las clases y las relaciones entre
ellas. Describe todas las relaciones estáticas entre las clases, es decir, es una
visión estática de un modelo.
• Behavior diagrams (Diagramas de comportamiento): Ponen particular
atención a la secuencia en la cual los objetos se relacionan entre si.
• Component diagrams (Diagrama de componentes): Muestra la organización
y dependencias de los componentes.

Una clase es representada por un rectángulo con tres apartados: el nombre de la clase,
los atributos y los métodos. Las dos últimas partes pueden ser omitidas.

Los atributos describen los datos que pueden ser almacenados en el objeto de la clase.
Determinan el estado de un objeto.

Los métodos describen las funciones que un objeto puede llevar a cabo. Determinan el
comportamiento de un objeto.

Hay dos formas de relaciones estáticas:


• Association
• Generalization/specialization

Asociación
Una asociación describe una relación semántica entre clases. La relación específica
entre objetos en estas clases es conocida como object link. Los object links son las
instancias de la asociación.

Una asociación es normalmente una relación entre diferentes clases (binary


association), pero puede relacionarse con sí misma (recursive association). En la
mayoría de los casos las asociaciones recursivas se usan para relacionar dos objetos
diferentes de una clase.

Cada asociación tiene dos roles: uno para cada dirección de la asociación. Cada rol
puede ser descrito con un association name y tiene una cardinalidad que muestra
cuantas instancias participan en esa relación. El nombre de asociación es escrito en
italics sobre la línea y puede contener una flecha para indicar la dirección de lectura. La
relación puede ser representada más concretamente con una clase especial donde se
describe las características de esta con sus atributos. Se conecta a la línea de asociación
con una línea discontinua.

4
Agregación es una caso especial de asociación donde se muestra que un objeto esta
compuesto por otros objetos. Se representa con un rombo vacío junto a la clase
principal.

Composición es una especialización de la agregación y muestra que el objeto contenido


no puede existir sin el agregado. La cardinalidad del agregado puede ser solo uno.

Generalización y especialización
Generalización y especialización son indicadas con una flecha triangular, la cual
apunta a la clase más general. Son relaciones bidireccionales.

Object Diagram
Un diagrama de objetos es una “foto” (“snapshot”) tomada durante la ejecución
del programa, que describe las instancias de las clases y las relaciones entre ellas (útil
solo para representar diagramas de clases complejos).

Secuence Diagram
Los diagramas de secuencia muestra los procesos o situaciones, centrándose en el
comportamiento durante el tiempo de secuencia: creación y eliminación de objetos así
como el intercambio de mensajes entre objetos. El object lifeline se representa con
una línea vertical discontinua. Una ‘X’ marca su final. El foco de control se representa
con un rectángulo vertical, y muestra los periodos activos de los objetos: un objeto esta
activa cuando ejecuta una acción, y un objeto esta indirectamente activo cuando esta
esperando al final de un procedimiento. Los mensajes se representan con una línea
horizontal y sobre ella se escribe este. La respuesta se puede representar de varias
maneras, entre ellas, con una línea discontinua.

5
Fundamental Object-Oriented Syntax Elements

Clases, Atributos, y Métodos

El concepto de clases es la base fundamental para todo lo pensado en orientado-objeto.

Una clase es un conjunto de objetos que tienen la misma estructura y el mismo


comportamiento.

Todos los componentes de la clase se encuentran definidos en la definition part. Los


componentes son atributos, métodos, eventos, constantes, tipos, e interfaces
implementadas. Solo los métodos son implementados en la implentation part.

La sentencia CLASS no puede ser anidada, eso es, porque no se puede definir una
clase dentro de otra clase.

Nota: sin embargo, si se puede definir una clase auxiliar para clases globales.

Atributos contienen la información que puede ser almacenada en los objetos de una
clase. Los atributos de una clase pueden ser de tres tipos: elementary, structered o
table-type. Estos pueden consistir de tipos de datos o referencias ya sean locales o
globales.

6
En clases, solo puedes usar el TYPE addition para hacer referencias tipos de datos.
Y solo puedes usar el LIKE para referenciar objetos de datos locales.

El READ-ONLY significa que un atributo público que fue declarado con DATA puede
ser leído desde afuera, pero puede ser cambiado por métodos en la misma clase.
Puedes usar solo READ-ONLY en la sección pública (PUBLIC SECTION) de la
declaración de una clase o en la definición de una interface.

Con TYPE REF TO, un atributo puede ser tipificado como cualquier referencia.

Puedes proteger atributos contra accesos desde fuera caracterizándolos como atributos
private. Los componentes private de la clase no pueden ser llamados directamente
desde fuera de la clase. Y no pueden estar visibles para los usuarios de fuera de la
clase.

Nota: el concepto friendship es una excepción a esta regla.

Los atributos que un usuario puede acceder directamente son los atributos public. Los
componentes públicos de una clase son a veces conocidos colectivamente como class’s
interface.

Sección de visibilidad privada es también conocida como information hiding o


encapsulación. En parte, esto es para proteger al usuario de una clase: se asume la
privacidad de los componentes de una clase pueden cambiarse en ese punto, pero su
interface mantiene lo mismo. Todos los usuarios externos pueden acceder sus
componentes a través de la interface de la clase, y puede continuar el trabajo usual
después de que el cambio ha sido hecho. El usuario no nota el cambio. Solo la
implementación interna fue cambiada.

Contrariamente, si los componentes públicos de una clase se han cambiado


incompatiblemente, cada usuario tendría que tomar estos cambios en cuenta. Por lo
tanto hay que usar atributos públicos muy poco, o evitar cambios incompatibles de
los componentes públicos en las clases.

7
Define los atributos privados en la PRIVATE SECTION de una clase. Y los
atributos públicos en la PUBLIC SECTION.

A través de sintaxis es imposible acceder a los métodos privados directamente desde


afuera. Sin embargo, es posible usando métodos públicos de la propia clase que
despliegan o cambian los atributos.

La signatura de un método público claramente establece que valores deben ser


transferidos, y que tipo de datos son asignados a ellos. Esto libera al usuario externo
de toda responsabilidad. El método en sí, es solo responsable de asegurar que todos los
atributos privados sean consistentes.

Por ejemplo, imagine que el MAKE y MODEL son atributos públicos. El riesgo sería
demasiado grande si a un usuario se le olvida rellenar uno de estos dos atributos o
especificar dos atributos inconsistentes. En cambio puedes usar un método público SET
TYPE para asegurarte que los valores son asignados correctamente a ambos
atributos. Un estricto control de sintaxis gobierna todas las llamadas que tienen
parámetros obligatorios de transferencia.

Hay dos tipos de atributos:

Instance attributes
Son los atributos que existen una sola vez por objeto, es decir, uno por cada
instancia de la clase ejecutada. Estos son definidos con la sintaxis DATA.

Statics attributes
Estos atributos existen una vez para cada clase y son visibles para todas las
instancias de la clase. Estos son definidos con la sintaxis CLASS-DATA.
Static attributes usualmente contienen información que aplica a todas las
instancias, tal como:
• Tipos y constantes
• Buffer de datos
• Información administrativa, tales como contadores

8
Methods son procedimientos internos en una clase que determina el comportamiento
de los objetos. Estos pueden acceder a todos los atributos en su clase y pueden cambiar
el estatus de otros elementos.

Los métodos tienen una signatura (interface de parámetros y excepciones) que los
habilita a recibir valores cuando son llamados y a pasar valores de vuelta a los
programas que los han llamado. Los métodos pueden tener cualquier cantidad de
parámetros IMPORTING, EXPORTING y CHANGING. Todos los parámetros
pueden ser pasados por valor o referencia.

Todos los parámetros de entrada (IMPORTING y CHANGING) pueden ser


definidos como opcionales en la declaración utilizando las palabras OPTIONAL o
DEFAULT. Estos parámetros no necesariamente deben ser transferidos cuando el
método es llamado. Si usas el OPTIONAL, el parámetro permanece inicializado de
acuerdo al tipo, y el DEFAULT te permite ingresar un nuevo valor.

Defines métodos privados en la PRIVATE SECTION de una clase. Defines atributos


públicos en la PUBLIC SECTION.

No es posible acceder directamente a métodos privados desde fuera. Sin embargo,


un método privado puede ser llamado por un método público.

Namespace: dentro de una clase, los nombres de atributos, nombres de métodos,


nombres de eventos, nombres de constantes y los nombres de los alias son compartidos
en un espacio llamado namespace. Tal como las subrutinas y los módulos de
funciones, hay un espacio local dentro de los métodos. Esto significa que las
declaraciones locales pueden hacer caso omiso de las de la clase.

Comparación de los Métodos estáticos y los de instancia.

Los Instance Methods son definidos usando la palabra de sintaxis METHODS.

Los Static Methods son de finidos al nivel de la clase CLASS-METHODS. La


restricción de que solo componentes estáticos pueden ser accedidos deriva de la forma
de implementarlos. Esto significa que los métodos estáticos no necesitan instancias,
es decir, pueden ser accedidos directamente a través de la clase.

9
Notación UML y secciones de visibilidad

En un diagrama UML se lista el nombre de la clase primero y luego los atributos y los
métodos debajo de ellos. La visibilidad de los componentes de una clase usando UML
es mostrada usando los caracteres + y -: alternativamente público y privado.

UML permite a los fabricantes de las herramientas de modelado crear sus propios
símbolos para visibilidad. Representaciones de características de visibilidad es opcional
y normalmente para modelos que serán implementados.

Los componentes estáticos son marcados con una línea baja _ .

Objetos: Instancias de Clases


Puedes usar clases para escribir aplicaciones completas usando solo componentes
estáticos. Sin embargo, la razón de la programación orientada a objetos es crear y
trabajar con instancias de clases.

Una clase contiene la descripción genérica de un objeto y describe todas las


características de todos los objetos de la clase que tiene en común. Durante la ejecución
del programa, la clase es usada para crear objetos discretos (instancias) en la memoria.
Este proceso es llamado Instantiation. Si esta es la primera vez que la clase es
accedida, la clase también es cargada a la memoria.

La sentencia CREATE OBJECT crea un objeto en la memoria. Los atributos son


entonces iniciales o asignados de acuerdo al valor especificado.

Independent references son referencias que no han sido definidas dentro de una clase.

El Garbage Collector es una rutina de sistema que es automáticamente iniciado cuando


el sistema de ejecución no tiene tareas importantes que hacer. Este todas las clases que
no son accedidas las elimina de forma automática.

Administración de referencias con múltiples instancias

Si deseas guardar varios objetos de la misma clase en un programa, puedes definir una
tabla interna que contenga una columna con la referencia de los objetos de esa
clase. Estos objetos pueden ser administrados en la tabla interna con las sentencias
usuales de APPEND, READ o LOOP.

Para usar condiciones lógicas, debe ser usado el pseudos-component TABLE_LINE


cuando usas las tablas internas. Para esto, los atributos deben ser públicos.

10
Accediendo atributos y métodos.

Llamando métodos

Un objeto que requiere el servicio de otro objeto envía un mensaje a otro objeto
brindando los servicios. El mensaje nombre la operación a ser ejecutada. La
implementación de esta operación es conocida como método.
Por lo tanto, el comportamiento de un objeto es determinado por sus métodos. La firma
de un método también puede ser utilizada para el intercambio de valores.

Instance Methods son llamados con CALL METHOD ref->method_name…

NO debe haber espacio antes de los paréntesis, pero si debe haber al menos uno
después de ellos.

11
Cuando llamas a un método, y este solo tiene un parámetro de importación, puedes
especificar el parámetro dentro del paréntesis sin otras adiciones. Cuando llamas a un
método que solo importa parámetros, puedes omitir la palabra EXPORTING.

Los parámetros RECEIVING, IMPORTING, y CHANGING son mutuamente


excluyentes.

Static methods (también llamados class methods) son llamados usando CALL
METHOD classname=>method_name…

Como los atributos estáticos, los métodos estáticos son diseccionados con el nombre de
su clase, ellos no necesitan instan ciarse.

Functional Methods

Los métodos que tienen un parámetro de RETURNING son descritos como métodos
funcionales. Esto significa que pueden tener parámetros EXPORTING o
CHANGING. El parámetro de RETURNING debe siempre se pasado por la sintaxis
VALUE.

Los métodos funcionales pueden ser llamados dentro de varias expresiones:

• Expresiones lógicas: IF, ELSEIF, WHILE, CHECK, WAIT


• Condiciones CASE, WHEN
• Expresiones aritméticas y expresiones bit: COMPUTE
• MOVE
• LOOP AT , WHERE.

Accediendo atributos públicos

Se puede acceder a atributos externos desde fuera de una clase de la misma manera que
se llama a un método.

Static attributes classname=>static_attribute


Instance attribute ref->instance_attribute

Constructores

Hay dos tipos de métodos en ABAP Objects. Estos no son generalmente llamados con
CALL METHOD, mas bien, son llamados implícitamente.

El constructor es un método especial de instancia en una clase, y siempre debe llamarse


CONSTRUCTOR.

El constructor es llamado automáticamente con la sentencia CREATE OBJECT.


Puntos a considerar al momento de crear constructores:

• Cada clase puede tener no más de un constructor

12
• El constructor debe ser definido en el área pública
• La firma del constructor solo puede tener parámetros de importing y
exceptions
• Cuando las exceptions son lanzadas en el constructor, las instancias no son
creadas.

Static Constructor

El static constructor es un método especial en una clase y es siempre nombrado


CLASS_CONSTRUCTOR. Es ejecutado no más de una vez por programa. El estatic
constructor es llamado automáticamente antes que la clase sea accedida, pero antes
cualquiera de las siguientes acciones son ejecutadas por primera vez:

• Creación de una instancia de la clase (CREATE OBJECT)


• Acceso de un atributo estático de la clase
• Llamar a un método estático de la clase

Siempre considerar los siguientes puntos cuando defina Constructores Estáticos:

• Cada clase tiene no mas de un constructor estático


• El constructor estático debe ser definido en la public area
• La firma del constructor no puede tener parámetros de importing o exceptions
• El constructor estático no puede ser llamado explícitamente

Self-Reference

Puedes direccional un objeto por sí mismo usando la variable ME dentro de una


instancia de métodos. Generalmente, no necesitas usar el prefijo me->, pero debes
usarlos para mejorar la lectura de los programas.

Sin embargo, es requerido cuando quieras mostrar la diferencia entre objetos de datos
local y los atributos de instancias con el mismo nombre.

13
Unidad 2: CONCEPTOS DE OBJECT-
ORIENTED Y TÉCNICAS DE
PROGRAMACIÓN
Herencia y Casting
Crear Generalization/Specialization Relationship usando
herencia
Specialization es una relación en la cual una clase (subclass) hereda todas las
características de otra clase (superclass). La subclase puede añadir nuevos componentes
(atributos, métodos…) y reemplazar las implementaciones de métodos heredados.

Una superclase es una generalización de sus subclases. Las subclases son


especializaciones de sus superclases

Características de Generalization/Specialization:
• Los componentes comunes solo existen una vez en la superclase, porque deben
tener una gestión centralizada.
• Los componentes de las superclases están disponibles para las subclases, esto
evita implementaciones redundantes.
• Las subclases contienen extensiones/cambios (“programming by difference”).
• Las subclases son dependientes de la superclase (“white box reuse”).

Generalization/Specialization provee una mejor estructura porque los elementos


comunes solo necesitan almacenarse en una localización central y están
automáticamente disponibles para todas las subclases.

Se necesita conocer la implementación de la superclase para decidir si los


componentes heredados desde ella son suficientes para la subclase o necesitan ser
ampliados.

Una inheritance relationship es definida por una subclase añadiendo a la definición de


la subclase la sentencia INHERITING FROM superclase_name. No existe herencia
múltiple en ABAP Objects.

14
La herencia debe ser usada para implementar generalization y specialization
relationship. Una superclase es una generalización de sus subclases. Las subclases
son especializaciones de sus superclases. En una subclase solo esta permitido
adiciones y cambios, no se puede eliminar nada de una superclase.

La herencia es una relación de uno a muchos, es decir, las subclases reconocen sus
superclases directas pero las superclases no reconocen sus subclases.

Redefining methods
Redefinition es cuando la implementación de un método heredado es cambiada por la
subclase sin cambiar la signatura. La redefinition no es posible sin la PRIVATE
SECTION (creo q public). Cuando se usa redefinition, se debe especificar una nueva
implementación para el método heredado. No es necesario definir los parámetros y
excepciones del método otra vez.

Dentro de la implementación de un método redefinido, se puede usar el prefijo


super->… para acceder directamente a los componentes en una superclase (clase) que
esta por encima de donde se esta trabajando.

Constructor de una subclase


Las subclases pueden usar el constructor de su superclase. Lo pueden hacer sin
necesidad de realizar ningún cambio sobre él, o ampliándolo añadiendo los parámetros
que sean necesarios.

El constructor de una superclase debe ser llamado dentro del constructor de la


subclase. Esto es debido a la specialization relationship.

Al constructor estático en una superclase se le llama automáticamente.

15
Herencia y visibilidad
La herencia provee una extensión del concepto de visibilidad: hay protected component
(PROTECTED SECTION). Se explica a continuación.

Cuando se define clases locales en ABAP Objects, se debe seguir la secuencia sintáctica
siguiente:
• Public section: Puede ser accedido desde fuera por todos los clientes.
• Protected section #: Solo puede ser accedido desde dentro de la clase y las
subclases.
• Private section: Solo puede ser accedido desde dentro, y los métodos no puede
ser accedidos directamente.

Las clases tienen componentes privados, a los que no se puede acceder desde la
subclase directamente aunque los hereden. Solo se puede acceder a los componentes
privados de las superclases indirectamente usando, desde la superclase, public o
protected methods.

Usando la private visibility section, se puede cambiar superclase sin necesidad de


conocer las subclases. Eso es porque solo se accede indirectamente a los componentes
privados.

Componentes estáticos y la herencia:


-Una clase que define atributos estáticos que son públicos o protegidos, comparten
este atributo con todas las subclases.
-Los métodos estáticos no se pueden redefinir.

Narrow Cast (Upcast)


Variables del tipo “reference to superclass” pueden hacer referencia a instancias
de subclases en tiempo de ejecución. Es decir, se asigna una subclass a una superclass.

Si se asigna una subclass reference a una superclass reference, esto asegura que todos
los componentes que pueden ser accedidos después del cast assignment están
actualmente disponibles en la instancia. La subclass siempre contiene al menos el
mismo número de componentes que la superclase.

16
El narrowing cast assignments se usa normalmente para prepara el acceso genérico.
Por ejemplo: da igual de que tipo sea el vehiculo (coche, camión), lo que importa es que
sea un vehiculo.

El usuario puede acceder a la instancia de la subclase de la misma forma que a la


instancia de la superclase. Sin embargo, esto esta restringido solo al uso de
componentes heredados.

Una reference variable siempre tiene dos tipos en tiempo de ejecución:


• Reference variable de tipo estática:
o Es definida usando TYPE REF TO.
o Es la misma durante todo el program flow.
o Define que atributos y metodos pueden ser accedidos.
• Reference variable de tipo dinámica:
o Es determinada por la asignación.
o Puede cambiar durante la ejecución del programa.
o Define que implementaciones son llevadas acabo con los inherited
methods.

Polimorfismo
Cuando objetos de diferentes clases reaccionan de distinta forma con la llamada de
un mismo método, es conocido como polimorfismo. La posibilidad de polimorfismo
es una de las principales ventajas de la herencia.

Usando function modules dinámicos, se puede programar de forma general en ABAP


Objects. Esto significa que el código fuente es menos self-explanatory (se explica por si
mismo) y mas susceptible de errores.

Widening Cast (Downcast)


Se puede copiar una reference back en una variable de tipo “reference to subclass”. Esto
se lleva a cabo con la siguiente sentencia. Superclase se asigna a subclase:
MOVE … ?TO … o, en forma corta ?=

Ahora si interesa de que tipo es el vehiculo, si es un camión o un coche.

17
La subclase contiene más componentes que la superclase.

Usando herencia
Se debe ver si hay una generalization/specialization relationship entre ciertas clases. Si
es así, se puede usar la herencia para representarlo.

Ventajas:
• Mantenimiento centralizado.
• Métodos genéricos de acceso.

18
Interfaces y casting
Areas de utilización para interfaces
Las interfaces difieren de la herencia normal en su área de uso. En términos de
programación existen unas grandes diferencias.

Desde un punto de vista técnico, las interfaces son superclases, que no se pueden
instanciar, no contienen una parte de implementación y solo tienen componentes
públicos. Sin embargo, se puede simular la herencia múltiple utilizando las
interfaces.

En ABAP Objects, las interfaces sirven principalmente para definir interfaces uniformes
(protocolos) para servicios. Varias clases pueden ofrecer estos servicios de diferente
manera, pero manteniendo la misma semántica. Las interfaces no contienen
implementación.

En ABAP Objects, los mismos componentes pueden ser definidos generalmente en


interfaces y clases.

Por ejemplo, se quiere permitir que múltiples clases implementen un servicio de


diferente manera, pero usando el mismo nombre de método y con una signatura
uniforme. Con la herencia común, se tiene que definir como un método compartido en
la superclase. Sin embargo, si no se tiene un modelo bueno para herencia con
superclases, hace falta definir una interfaz y luego definir el método en esta. Se puede
comparar este caso con el de generalización de superclases.

19
Comparándola con la herencia común, la distribución de roles es algunas veces
diferente: El usuario generalmente define la interfaces. En las interfaces, el usuario
(quien usa la interface) describe los servicios que quiere que el proveedor ofrezca. Cada
clase puede decidir ahora por si misma si sirve la interface que ofrece actualmente
los servicios definidos. Este caso es parecido a la especialización con subclase.

Como la herencia común, este acceso a servicios es genérico, se utiliza una referencia
que es tipificado en el interface. Se pueden construir polimorfismos con interfaces.

En UML, las interfaces se representan igual que las clases. Sin embargo, además de su
nombre, hay que poner el estereotipo <<interface>>. El uso de una interface se
expresa con una línea discontinua desde quien lo usa al interface. El estereotipo
<<user>> es opcional. Que una clase implementa una interface se representa con línea
discontinua de la clase a la interface.

Creando relaciones de generalización/especialización


utilizando interfaces
En ABAP Objects, los mismos componentes se pueden definir en una interface y en una
clase. Sin embargo, las interfaces no saben los niveles de visibilidad de los
componentes, es decir, todos los componentes son públicos.

20
Las clases implementan las interfaces de la siguiente manera:
-El nombre de la interface se lista en la parte de la definición de la clase con la sentencia
INTERFACES. Esto ha de ser en la parte pública, solo pueden ser implementados
públicamente.
-Los métodos de la interface deben ser implementados en la parte de implementación
de la clase.
-Los componentes definidos en la interface pueden ser llamados en la parte de
implementación de la clase.

Los componentes de la interface se distinguen de los otros componentes en la clase con


el prefijo de nombre de interface y el siguiente símbolo ~.
Interface name~ component name

Para simplificar el acceso a los componentes de interface, se pueden utilizar alias.


Ejemplo:

ALIASES a_1 FOR lif_1 method_1.

El método de interface lif_1 method_1 se puede llamar con: ref->a_1.

21
A los componentes de las interfaces solo se pueden acceder usando una referencia de
objeto en la que su clase implementa la interface. Sintacticamente, esto se hace con el
operador ~, como en la implementación de la clase.

Alternativamente, se pueden utilizar los alias definidos en la implementación de la clase


para los componentes de interface.

Polimorfismo con interfaces


Como las interfaces no se pueden instanciar, una referencia de interface solo se
puede referir a instancias de clases que tienen implementada la interface. Si se
quiere construir polimorfismos con interfaces, hay que utilizar narrowing cast para
copiar una referencia a la variable de referencia que esta tipificado con la
interface. Como en la herencia común.

Si la clase tiene implementada una interface, es seguro que todos los componentes que
se pueden acceder sintacticamente después del casting, están disponibles en la instancia.
La interface siempre contiene como mínimo los mismos componentes que la clase de
implementación.

Un usuario puede llamar a la instancia de una clase de implementación utilizando la


interface. El prefijo del nombre de la interface y el operador son omitidos. Sin embargo,
el usuario está obligado a utilizar los componentes desde la interface.

En el ejemplo mostrado, los métodos DISPLAY_PARTNER y


CHECK_AVAILABILITY de la interface LIF_PARTNER solo pueden ser accedidos
después de asignar la variable de referencia R_PARTNER. No es posible acceder a los
componentes específicos de la instancia de la clase LCL_RENTAL usando la variable
de referencia R_PARTNER.

22
Un caso típico de uso de narrowing cast es la preparación para acceso genérico. En
el ejemplo de arriba (LCL_TRAVEL_AGENCY) necesita manejar varios tipos de
negocios en una sola lista. El tipo de linea de la tabla interna, tiene que ser tipificado
como una referencia a la interface LIF_PARTNER.

Los métodos relevantes se definen en la interface LIF_PARTNER y se implementan en


cada una de las clases.

Objetos de diferentes clases(hotel, rental y carrier) pueden mantener una tabla interna,
tipificado con referencias a la interface (LIF_PARTNER). Los componentes definidos
en la interface pueden ser después accedidos uniformemente.

Para este ejemplo se necesita el método ADD_PARTNER. Este copia, la referencia a


todos estos tipos de negocios, en la tabla interna. El parámetro que se importa debe estar
tipificado como la referencia a la interface.

También se puede construir el polimorfismo para las interfaces. Las referencias a


interface se pueden usar para llamar a métodos, donde pueden ejecutarse diferentes
implementaciones dependiendo del objeto de la referencia.

23
El tipo dinámico de la variable de referencia se utiliza para buscar la
implementación del método. En el ejemplo anterior, r_partner->display_partner() ,
utiliza la clase de la instancia en la que r_partner para buscar la implementación de
display_partner.

Cuando los objetos de diferentes clases reaccionan al mismo método, se conoce como
polimorfismo.

La opción de construir polimorfismos, es uno de los puntos fuertes de las interfaces. El


sistema de ejecución busca la implementación adecuada de un método dependiendo del
cliente.

Los polimorfismos se pueden utilizar en programas que son mayormente


genéricos, esto es, que no necesitan cambios significativos si se quiere añadir casos
de usos nuevos.

En el ejemplo superior se puede añadir alquiler de barcos y el programa no se vería


afectado.

Si se quiere asignar una referencia de interface a una referencia de clase donde la


clase implementa la interface, hay que utilizar el operador de widening cast
MOVE…?TO… o con la abreviación ?=.

En el ejemplo superior, todos los componentes de la instancia LCL_CARRIER pueden


ser accedidos después de la asignación, usando la refeencia R_CARRIER.

Este punto de vista se conoce como widening cast o downcast.

Un uso típico de widening cast es cuando un componente específico de una instancia


necesita ser llamado cuyas referencias son mantenidas en variables que son
tipificadas en la interface. En el ejemplo una agencia de viajes
(LCL_TRAVEL_AGENCY) necesita reservar un vuelo pero mantiene todos las
referencias a negocios en una tabla interna, que ha de estar tipificada en la interface
LIF_PARTNER.

24
Jerarquía de interfaces
Se ha visto varias veces que una implementación de interface se parece mucho a la
herencia común.

En el ejemplo, se necesita saber cuando sería conveniente definir un servicio “room


reservation” en la interface LIF_PARTNER. En este caso las clases LCL_CARRIER y
LCL_RENTAL deberían implementar el metodo apropiado porque tienen integrado el
interface LIF_PARTNER. Sin embargo, la implementación de una reserva de habitación
no es posible en aerolíneas o alquileres de coches.

Sin embargo, como hay varios tipos de negocios para los que la implementación sería
factible, el método necesita ser definido centralizadamente y no individualmente para
moteles y hoteles. Por otra parte, existe la opción de extender el modelo fácilmente.

25
Las interfaces pueden incluir interfaces. Puede existir por lo tanto una jerarquía de
interfaces. Representa una extensión de la interface incluida.

La interface que tiene otras interfaces se conoce como compbound interface. Una
interface incluida representa un componente de otra interface y se conoce como
component interface. Una interface que no tiene más interfaces incluidas es
elementary interface.

Para llamar a los métodos, component_interface~component_name.

Ventajas
Si no hay posibilidad de enlazar clases en cuanto a su herencia, creando relaciones de
generalización o especialización mediante interfaces se puede tener las siguientes
ventajas:
-Separación de protocolo y servicio
-Posibilidad de simular herencia múltiple
-Accesos a métodos seguros y genéricos

26
Eventos
Aparte de los atributos y métodos, las clases pueden contener un tercer tipo de
componente: eventos. Instancias de eventos se pueden lanzar con las instancias de las
clases, mientras que las instancias estáticas de eventos se pueden lanzar con la propia
clase. Los eventos también se pueden definir como componentes de interface.

Dadas las circunstancias idóneas, los métodos del receptor o handler pueden
reaccionar al lanzamiento de este evento. Esto significa que el sistema de ejecución
puede llamar a estos métodos del receptor después de que el evento se lance. En otras
palabras el método del handler no se llama directamente por el cliente.

Cuando se está desarrollando la clase que lanza el evento, no hace falta saber nada
acerca de la clase que lo recepciona. La clase lanzadora (triggering) informa al resto
de clases que se encuentran en el programa de ejecución.

Un evento puede tener parámetros de exporting, lo que quiere decir que el programa
llamador determina el protocolo.

En este ejemplo, después de crearse una instancia de la clase vehicle, se lanza el evento
“vehicle created”. Este evento es recibido por diferentes instancias y es procesado por
cada una.

No hay que confundir un evento en orientación a objetos con eventos en ABAP en


tiempo de ejecución (START-OF-SELECTION…).

En diagramas de clase UML se utiliza el esteriotipo <<handlesEventOf>> desde la


clase capturadora (handler) a la clase que lo lanza. La definición del evento y la
signatura solo aparecen implícitamente en la clase capturadota (handler) con el método
capturador (handler). Estos métodos están separados del resto con el estereotipo
<<eventHandler>>.

27
Triggering and handling events
Lo siguiente resume los pasos de programación necesarios para el control de eventos.

Hay que tener en cuenta que dependiendo del estado de la aplicación que se desarrolle,
no son necesarios todos los pasos de programación. La separación de la causa y el
efecto en la programación, debería verse reflejada a la hora de construir aplicaciones
complejas. Muchas veces, el evento ha sido lanzado y lo único que hay que hacer es
crear otro event handler.

Mediante una clase, las instancias de eventos, son definidas utilizando la sentencia
EVENTS, mientras que los eventos estáticos son definidos con CLASS-EVENTS.

Los eventos solo pueden exportar parámetros, los cuales se tienen que pasar por
valor, como una copia.

Una clase o una instancia puede lanzar un evento en tiempo de ejecución utilizando
RAISE EVENT. Tanto las instancias de eventos como los eventos estáticos se pueden
lanzar en métodos de instancia. Solo los eventos estáticos se pueden lanzar en métodos
estáticos.

Cuando ocurre un evento, los métodos del receptor que están registrados para este
evento, son llamados en secuencia. Por supuesto, estos métodos receptores, pueden
lanzar más eventos ellos mismos.

28
Todo este proceso se muestra abajo.

Las instancias de eventos o métodos estáticos se pueden definir en una clase para
lanzar los eventos. Para hacer eso, hay que especificar el evento (FOR EVENT) y la
clase o interface en el que el evento es definido (OF).

Si el evento contiene exporting parameters y se quiere llamar a estos


sintacticamente, hay que especificar los exporting parameters seguido del
IMPORTING en al definición del método. La signatura del método receptor (handler)
puede consistir en no más que los exporting parameters del evento asociado. Los
parámetros son tipificados por el método receptor(handler) durante la definición del
evento. El objeto que lanza el evento determina el protocolo.

Además el parámetro importing predefinido SENDER siempre se puede pasar. Usando


este parámetro se puede referenciar al objeto event-trigger en el método receptor
(handler).

Aunque normalmente se llamen a los métodos receptores (handler) mediante RAISE


EVENT, también se les puede llamar explícitamente mediante CALL METHOD.

29
Registro de eventos
La definición de los métodos receptores solo especifican como y a que evento de
que clase el método va a reaccionar. En ejecución, se necesita determinar que posibles
reacciones se van a dar y cuando van a ocurrir.

Estas especificaciones son comúnmente conocidas como registration (registro). El


registro se da siempre usando el trigger. Cuando se lanza el evento, la ejecución utiliza
el registro de trigger para determinar a que métodos receptores (handler ) de evento hay
que llamar.

En el ejemplo de arriba, los métodos receptores (handler) de la clase rental y la clase


vehicle registration, están definidos para el evento de la clase vehículo. Sin embargo
solo se puede predeterminar que instancias rental calr y vehicle registration van a
reaccionar a la instancia vehicle, y cuando lo van a hacer.

Los registros se pueden revocar.

30
Los eventos se registran usando SET HANDLER. El registro solo es activo en el
programa de ejecución.

Con las instancias de eventos, FOR esta siempre permitido por la referencia del
objeto que lanza el evento. Alternativamente, se puede utilizar ALL INSTANCES.
Así, se pueden registrar objetos que todavía no han sido creados.

La adición:
ACTIVATION ‘X’ es opcional durante el registro. Para deshacer el registro, utilizar
ACTIVATION space.

Se pueden registrar varios métodos, con una sola SET-HANDLER:

Set handler
Ref_handler->on_eventname_1
…..
Ref_handler->on_eventname_n
FOR….

Si varios métodos se han registrado para un evento, la secuencia en la que los métodos
receptores (handler) se llaman, no esta definida. No hay una secuencia garantizada
en la que los métodos receptores (handler) de un evento son llamados.

Si se registra un nuevo event handler mediante un metodo receptor (handler) de evento


para un evento que ya ha sido lanzado, este event handler se añade al final de la
secuencia. Si un event handler se quita del registro en un metodo receptor (handler) de
evento, este handler se elimina de la secuencia de event handler method.

Todos los objetos o clases que tienen definido un evento, tienen una tabla interna:
handler table. Todos los handler method que se registran a los eventos están listados en
la tabla.

31
Los objetos que son registrados para un event handling, no se borran por el recolector
de basura si no quedan más referencias a ellos.

Visibility sections in Event Handling


Los eventos están sujetos al concepto de visibilidad y pueden ser: públicos, privados o
protegidos (protected).

La visibilidad de un evento determina quien está autorizado a capturar (handle) el


evento.
-public: todos
-protected: usuarios que tengan esa clase o subclase
-private: solo con esa clase

La visibilidad de un método receptor (handler ) controla quien esta autorizado a


registrar el método, es decir, la ubicación en la que se puede programar el SET
HANDLER.
-public: En cualquier lugar del programa.
-protected: Solo puede capturarse por usuarios que tengan la clase o subclase.
-private: Solo con la clase.

Los métodos capturadores (handler ) de eventos, tendrán que tener una visibilidad igual
o más restrictiva que la de los eventos a los que se refiere.

32
Unidad 3: Objetos de Repositorio de
orientación a objetos
Clases globales e interfaces
Creación de clases globales e interfaces
Como con las subrutinas, las clases locales o interfaces solo pueden ser usadas dentro del
programa en el que son definidas e implementados. La sentencia CLASS es una sentencia local,
declarativa en el programa. Como la declaración TYPES define tipos de datos locales la
sentencia CLASS define tipos de objetos locales.

En ambas casos, es irrelevante si el texto del código fuente este guardado separado en
programas incluidos.

Por otro lado las clases globales o interfaces globales son objetos individuales del Repository
con todos los atributos normales (la integración activa, la gestión de versiones de documentos,
sistema de transporte, etcétera). Convención de nombres (Y*, Z*, o un nombre especial del
cliente.) es el mismo que el usado para el nombre de otro objeto del Repository.

Una herramienta de mantenimiento especial está disponible para las clases globales en el ABAP
Workbech desde la versión 4.6A de R/3 de SAP: el class builder.

El área de navegación del Object Navigator hace que sea una herramienta de desarrollo ideal
para todos objetos del Repository. También soporta el Class Builder. Como con otros objetos de
Repository, la manera más fácil de crear una nueva clase global es usar el menú contextual en el
área de navegación. Seleccionar el nodo paquete o nodo de clase dentro de un paquete.

Un cuadro de diálogo pide crear los atributos adicionales para la nueva clase.

La clase global o la interfaz global son mostradas por la tabla del Class builder en la zona de
editor del Object Navegator.

Escoger la pestaña de Attributes para abrir la lista de todas definiciones de atributos en la clase.
Se pueden definir los nuevos atributos aquí.

Se pueden usar las input help cuando se está definiendo los tipos de atributos. Recordar usar
descripciones breves significativas.

33
Escoger la pestaña Methods para abrir la lista de todos los métodos definidos en las clases. Se
pueden definir los nuevos métodos aquí. Se puede usar los input help cuando se definen los
atributos. Recuerde usar descripciones breves significativas.

Hay ventanas de editor distintas para la signatura y la implementación.

Escoger el botón Constructor para definir una instancia de constructor. El nombre de constructor
es escogido automáticamente y las posibilidades de selección en la ventana de editor para la
signatura están restringidas apropiadamente.

Si se quiere incluir una interfaz global en la clase global, se debe introducir el nombre de la
interfaz en la pestaña Interface. En cuanto se ha hecho eso, todos los componentes de la interfaz
aparecen automáticamente bajo las pestañas relevantes de acuerdo la convención de nombres y
el operador de resolución de interfaz

34
En lista de métodos, seleccionar el método y escoger el botón de Parameter para ir al
mantenimiento de la signatura. Se pueden definir los nuevos parámetros formales aquí.

Se puede usar el input help cuando se definen los atributos. Recordar usar descripciones breves
significativas.

Se puede desplazar entre las signaturas usando los botones Previous Method o Next Method.
Escoger el botón Methods para volver a la lista de metodos.

En el lista de métodos, seleccionar un método (doble - clic) o sobre el método seleccionado,


escoger el botón Source code para ir al mantenimiento de código. Se pueden implementar las
modificaciones aquí.

35
Escoger GotoMethod definition si se quieren cambiar los atributos del método
durante la implementación.

También se puede definir los atributos, los métodos, o eventos en el menú contextual en el area
de navegación del Object navigator. Las propiedades son mantenidas en un cuadro de diálogo, y
no en la tabla que hemos visto antes.

Se pueden probar clases globales activas


.
Las plantillas de clase son asignadas temporalmente. Los estáticos son asignados
inmediatamente, mientras que los componentes de instancia son asignados cuando se escoge el
Instance botón.

El sistema solamente lista los componentes públicos. Los métodos pueden ser evaluados usando
el icono call method.

Se puede evaluar triggering de los eventos en una clase de la siguiente manera:


1. Seleccione un evento.
2. Escoger Handler. Este registra un metodo estandar para el evento.
3. Llamar al método en el que el trigger de evento está implementado.

36
El evento que se ha lanzado y todos de los parámetros exportados actuales son mostrados en
una lista.

Importando clases locales e interfaces


Este procedimiento es una manera fácil de hacer copias globales de clases locales e interfaces
locales.

Procedimiento
1. En el menú SAP easy acces, escoger Tools  ABAP Workbench  Development 
Class Builder o usar la transaccion SE24
2. De la pantalla inicial de SE24, escoger Object type  Import  Local program classes.
3. Introducir el nombre del programa principal, si las clases locales e interfaces han sido
definidos con programas incluidos (include), seleccionar expand includes
4. Escoger Display Classes/Interfaces.
5. Introducir los nombres para las clases globales y las interfaces que se quieren crear.
Recordar la nomenclatura de nombres del cliente, si es aplicable.
6. Seleccionar las clases globales e interfaces que se quiere crear y escoger el botón de
Import.

Otras funciones del class builder


Las relaciones de herencia entre clases globales se pueden indicar sobre la pestaña Properties.

Se puede indicar la superclase después de escoger superclase.

37
Para redefinir un método heredado, seleccionar el método relevante en la lista y
seleccionar el botón Redefine. Alternativamente se puede utilizar el menú contextual en
el área de navegación.

Se pueden definir tipos locales en las clases globales. Esto incluye clases locales en
particular.

Técnicamente no se definen clases con clases dentro, pero si una clase que es local en el
repositorio de una clase global.
Todos componentes de la clase global tienen acceso a estos tipos locales, pero son
encapsulados si se trata de acceder a ellos desde fuera.

Lo mismo ocurre para interfaces locales en clases globales.

Para editar las partes de implementación de estas clases locales , escoger el Botón Impl. (para
las implementaciones de clases locales).

38
Para mejorar el conocimiento de herencia y componentes de interfaz, se puede poner Group by
classes and Interfaces señalado en el User –Specific Settings para el Class Builder. El sistema
mostrará los componentes de la clase global en una estructura.

También se pueden ordenar todos componentes por cinco criterios, en tres niveles. Para hacer
esto, mostrar la caja de diálogo apropiada escogiendo el botón de Sort.

Addition of Global Classes Using the ABAP Editor

Al igual que otros objetos de repositorio, las clases globales e interfaces se han añadido en el área
de la navegación del OBJECT-NAVIGATOR.

39
De esta manera las ventajas también se aplican a trabajar con clases globales e
interfaces.

En la área de navegación, hacer clic en un nombre de clase y arrastrarlo al área edición. Este
crea un instrucción CREATE OBJECT. Después se debe añadir la variable de referencia y los
parámetros actuales, si es aplicable, a la sentencia.

Alternativamente, se puede escoger el botón Pattern. La sentencia CREATE – OBJECT está


bajo el ABAP Object Pattern. Se puede generar la sentencia usando la input Help.

En el área de navegación, hacer clic en un nombre de método y arrastrarlo al área de edición.


Esto crea la instrucción CREATE-METHOD. Se debe añadir la variable de referencia y los
parámetros actuales , si es aplicable, a la sentencia.

Alternativamente, se puede escoger el botón Patthern. La sentencia CALL- METHOD está bajo
el ABAP Object Patthern. Se puede generar la sentencia usando la input Help.

The Refactoring Assistant


En un mundo ideal, todas clases, interfaces, y las asociaciones entre ellas se podrían modelar
con UML, antes de que el desarrollo empiece. Sin embargo, en algunos casos, el modelo tiene
que ser adaptado durante la fase de implementación. El Refactoring Asistant ofrece opciones
amigables (user-friendly) para el usuario, para cambiar objetos del Repository.

40
Por ejemplo, se puede usar el Refactoring Asistant para mover los componentes de una clase
dentro de la jerarquía de herencia. Consejo: para una lista completa de las funciones del
Refactoring Asistant, consulte la biblioteca de SAP.

Trabajando con las herramientas es simple, ya que es basado en diálogos arrastrar y soltar
(Drag&Drop).

En general, no se ajusta la implementación de métodos, ya que no se puede saber cuánto


necesitas modificar los objetos de referencia después de realizar estos cambios.

Moviendo la definición de métodos de una clase global a una


interfaz implementada
1. Cambiar al modo de edición de una clase global que implementa una interface global
2. Escoger tools->Refactoring Asistant.
3. En la estructura de árbol que aparece, abrir la carpeta para el método que se quiere mover y para el
destino, en este caso la interface implementada.
4. Mover el método de la interfaz.
5. Guardar.
6. también se necesitará adaptar las sentencias que llaman al método en el código fuente.
7. Activar tanto la clase como la interfaz.

Programación Orientada a objetos: ALV Grid Control


El Control Framework es una colección de clases globales e interfaces que pueden ser usadas
para añadir controles SAP GUI en programas ABAP Object, sin considerar la plataforma.
Muestra como usar eficazmente clases estándar de SAP con la referencia al ampliamente usado
ALV Grid Control.

El ALV Gris Control es una herramienta que se puede usar para mostrar listas no jerárquicas en
un formato estándar. La lista de datos es mostrada en tablas. Es muy fácil trabajar con, pocos
pasos de programación que tienen que ser realizados.

El ALV Grid Control contiene varias funciones estándar interactivas que los usuarios de las listas
a menudo necesitan, por ejemplo, imprimir, exportar, etcétera. Un desarrollador, tiene la opción de
ocultar estas funciones estándar. Cuando se requiera, se puede adaptar las implementaciones a las
necesidades de la aplicación. También se puede añadir funciones propias a la barra de
herramientas de la aplicación.

El enlace técnico entre la pantalla y el control de aplicación esta provista por container
controls. En general, los controles de aplicación (ALV Grid Control , Tree control, Picture
Control, etcétera) están siempre contenidos en este control , que está conectado con la pantalla.

Hay diferentes tipos de container controls. Sin embargo, todos ellos incorporan funciones de
control fundamentales, tales como barras de desplazamiento (scroll).

Se necesita para crear una instancia de cada una de las clases globales
CL_GUI_CUSTOM_CONTAINER y CL _GUI _ALV _GRID.

41
Para la visualización normal, los siguientes pasos de programación son suficientes:

1. Usar el editor de fullscreen del Screen Painter para definir una área de control sobre la
pantalla.
2. Crear una instancia de la clase CL_GUI_CUSTOM_CONTAINER y transferir el nombre del
área de control al constructor.
3. Crear un instancia de la clase CL_GUI_GUI_ALV_GRID y transferir el nombre del area de
control al constructor.
4. Llamar al método SET_TABLE_FOR_FIRST_DISPLAY de la instancia del grid control, y
transferir la tabla interna estándar a este.

Si esta tabla tiene un global row type, se puede transferir el nombre de esta estructura global al
mismo método. La instancia ALV grid Control crea automáticamente el field catalog.

Si se cambia el contenido de las tablas internas mientras el programa está ejecutándose,


solamente se necesita llamar el método REFRESH_TABLE_DISPLAY en el paso de diálogo
relevante para refrescar la vista.

Un ALV Grid Control puede reaccionar frente al doble clic del usuario. Como posible reacción,
se puede lanzar un proceso en el que se muestra información adicional. En el ejemplo que
aparece, la reserva de datos para vuelos individuales de clientes, o los datos sobre la aeronave,
también podrían mostrarse para los datos del vuelo. Técnicamente, esto es ejecutado capturando
el evento DOUBLE_CLICK con un manejador (handler) de método.

42
Un método handler puede ser un método de clase (método estático) o una instancia de método
de un objeto. Si un método de clase es definido como un método handler, ningún objeto de la
clase gestora (handled) necesita ser instanciado para usar el método.

Para crear un objeto handler para un evento, definir primero una clase. Esta clase tiene un
método público (en la PUBLIC SECTION) que puede reaccionar a un evento. Durante la
implementación del método handler, definir el código fuente que debe ejecutarse cuando el
evento es provocado. El método recibe la información lanzada por el evento desde la posición
de Mouse cuando se hace doble clic, y crea un mensaje de información, en el ejemplo se
muestra la fila y el campo del clic de ratón.

Programación Orientada a objetos: Business Add-Ins


A diferencia de las customer exits, las BADIS del software cambiado se tienen en cuenta aquí.
En general, el típico proceso no solamente consiste en proveedores y usuarios: muchos
intermediarios participan etc. Por ejemplo, un programa de aplicación de SAP puede ser
extendido con una solución para industria; el mismo programa podría ser ampliado por el
cliente otra vez.

Con una (BAdI), un programa de aplicación de SAP provee una opción de mejora a través de
una interfaz y una clase adaptadora que implementa la interfaz.

La interfaz puede ser implementada por varios usuarios. Hay posibilidad de implementaciones
múltiples.

43
Cuando se define una BAdI, se debe especificar una interfaz (IF_EX _ < badi >) con los
correspondientes métodos definidos formalmente. La clase adapter que se genera
automáticamente durante la definición del interfaz (CL_EX _ < badi >) tiene la función de
llamar a todas las implementaciones activas de la BAdI. Esto no necesita ser codificado, pero
ocurre en la clase adapter en una secuencia indefinida. Cuando se tiene varias implementaciones
activas, no hay ninguna secuencia de procesamiento predeterminada.

Para crear una BAdI, se utiliza la herramienta BAdI builder (Tools ABAP Workbench 
Utilities Business Add-Ins  Definition) (SE18).
Una vez que el nombre se ha emitido para la BAdI, el sistema sugiere nombres para el BAdI
interface y el clase adapter. Para asegurarse de que se mantenga una clara visión general, se
recomienda que en asignar estos nombres.

Si se hace doble click sobre el nombre de interfaz, el sistema va al Class Builder, donde los
métodos de interfaz pueden ser definidos.

Después de que los métodos de interfaz son definidos, ¡la interfaz debe ser activada!

La llamada de un BAdI es mostrada en la figura superior.

Primero, una variable de referencia debe ser definida del tipo "Referente to the Business Add-In
interface".

Un objeto de la clase adapter es instanciada por la llamada del método estático


GET_INSTANCE de la clase CL_EXITHANDLER. R_ADAPTER apunta a la instancia.

Los métodos de interfaz del BAdI pueden ser llamados a través de esta referencia de objeto.

44
Antes de que un BAdI pueda ser implementado por el cliente, su nombre debe ser definido de
antemano. Cuando se busca este nombre de BAdI, se puede usar uno de lo siguiente
mecanismos de búsqueda:
-La información de Repository del sistema (SE84)
-La jerarquía de aplicación (SE81)
-La guía de implementación a través de SPRO
-Navegando directamente vía F1 -> la información técnica del programa de aplicación y buscar
para la instanciación de la clase adapter de la BAdI usando la llamada CL_EX-ITHANDLER
= > GET_INSTANCE.

Hacer doble clic en la variable de referencia (aquí, R_ADAPTER) te lleva a su definición, en


que la interfaz de BAdI es usada para tipificar. Se puede derivar el nombre de la BAdI del
nombre de la interfaz.

Si el nombre del BAdI ha sido determinado, el BAdI puede ser implementado después de que se
estudie la documentación sobre este tema. La implementacion es realizada mediante la
implementation maintenance (Tools  ABAP Workbench  Business Add-Ins
Implementation). Alternativamente, se también puede ir a la implementación navegando en el
menú de la BAdI definición.

Para implementar una BAdI, un nombre de BAdI implementation tiene que ser proporcionado.
La convención de nombres aquí, como de costumbre, es Z < impl >. Un cuadro de diálogo
aparece para seleccionar el correspondiente BAdI.

El código que debe ser implementado se almacena en un método de una clase cliente
automáticamente generada. Por esta razón, el nombre de la clase de implementación debe ser

45
introducido en el diálogo. El nombre: "Y o Z" (el prefijo de namespace), "CL" (para clases),
"IM _" (para implementaciones)” y "< impl >" (el nombre actual de la implementacion).

Después de hacer doble clic sobre uno de los métodos BAdI, se puede introducir el código del
método. Por supuesto, también se puede crear los métodos auxiliares en la implementación de
clase para mejorar la estructura del código requerido del método de BAdI.

Transacciones de Orientación a objetos como tipos de


transaccones
En el Transaction maintenance, se puede crear una clave de transacción como una transacción
orientada a objetos (OO). Esto quiere decir que se enlaza el código de transacción con cualquier
servicio de transacción de los servicios de ABAP Object para objetos persistentes o a un
método público en una clase global o local de un programa. Cuando se llama a un tipo de
transacción OO que es vinculada con una instancia de método, el sistema crea
automáticamente una instancia de la clase en su propia sesión interna y luego ejecuta esta
instancia del método.

Si el OO transaction Model está seteado, el código de transacción es vinculado con el servicio


de transacción de los servicios ABAP Object. A la inversa, si no es determinado, se puede
llamar a cualquier método en una clase global o local.

Los usuarios ahora tienen la oportunidad de llamar los métodos por si mismos (a través de
opciones de menú, command field entries, etc.).

Creando una transacción OO


-Llamar al diálogo de costumbre para crear un código de transacción e introducir un
texto breve.
-Escoger la opción method of a class (la transacción de OO) como un objeto inicial.
-Dejar el indicador OO Transaction model no chequeado si se quiere enlazar el código de
transacción con un método de instancia normal.
-Introducir el Class name y el method. Poner el indicador Local in program, si se está usando
una clase local, introducir el nombre de programa.
-Guardar el código de transacción.

46
Unidad 4: ALV Grid Control
ALV Grid Control
ALV es una herramienta que permite visualizar listas no jerarquizadas en un formato
estandar. La lista de datos se muestra en la pantalla mediante una tabla y es muy user
friendly.

ALV tiene unas funciones estándar interactivas que se muestran arriba de la pantalla
como imprimir. Estas se pueden ocultar y también se pueden añadir nuevas
funcionalidades o modificar las existentes en la barra de herramientas de la aplicación.

El contenedor es la conexión entre la screen y la aplication control. Los aplication


controls se tienen que embeber dentro de un container control, que hay que conectar con
la pantalla.

Hay diferentes tipos de contenedores. Todos encapsulan funciones básicas de control.


(por ejemplo scroll bars).

Hay que crear dos instancias de las siguientes clases globales:


CL_GUI_CUSTOM_CONTAINER y CL_GUI_ALV_GRID.

Para una visualización estándar, basta con programar estos pasos:


1- Definir un custom control area en la pantalla utilizando el graphical fullscreen
editor del screen painter.
2- Generar instancia de CL_GUI-CUSTOM_CONTAINER y pasar al constructor
el nombre del custom control area que se ha definido.
3- Generar instancia de CL_GUI_ALV_GRID y asignar al constructor la referencia
a la instancia del container control que se ha generado.
4- Llamar al método de la instancia de Grid Control
SET_TABLE_FOR_FIRST_DISPLAY y asignar a este la tabla interna estándar
y los datos de aplicación.

Si el método tiene una row type global, se le puede dar el nombre de esta estructura
global. El field catalog se creará por la propia instancia de grid control.

47
Si el contenido de la tabla interna que se muestra se modifica basta con llamar al
método REFRESH_TABLE_DISPLAY.

ALV Grid Control - Field catalog


El field catalog es un formato de los datos del display area. Para que este se pueda
generar automáticamente se puede tener un proxy instante. Para las line types que son
definidas en el diccionario ABAP, solo se necesita informar al proxy instante del ABAP
Dictionary.

Alternativamente, o como adición a esto, se puede proveer la instancia proxy con esta
información de visualización usnado una tabla interna adicional. El tipo global de la
tabla interna es LVC_T_FCAT cuya line type es LVC_S_FCAT.

Los típicos ejemplos de donde se necesita transferir el field catalog son:


• La tabla interna con los datos tiene un line type con referencia al diccionario,
pero el orden de mostrarlos o la cabecera es diferente.
• La tabla interna tiene columnas exclusivas que no están en la estructura del
diccionario.

Los field catalog se generan de maneras diferentes, y se pueden dar esto 3 casos:
-Caso 1:
Todos los campos de una estructura aparecen en la tabla de datos con el mismo nombre.
Estos son los campos a mostrar. En este caso se puede hacer que la instancia Proxy cree
el field catalog. Las columnas que no se definen en la estructura no son mostradas.
-Caso 2:
Todos los campos de la estructura global aparecen en la tabla de datos con el mismo
nombre. Sin embargo, los requerimientos del diccionario abap han de ser cambiados o
las columnas adicionales han de ser mostradas.
En este caso el field catalog se debe crear por el programa llamador.
-Caso 3:
La tabla de datos no contiene referencia alguna al diccionario ABAP o solo contiene
referencias a data elements o estructuras globales individuales. En este caso el field
content ha de ser creado enteramente por el programa que lo llama.

48
Descripción casos 2 y 3

En el programa que llama, se crea el field catalog de la siguiente manera:


• Se define una tabla interna para el field catalog del tipo en LCV_T_FCAT y una
linea compatible como un work area

• Se rellenan los campos de la work area para cada campo relevante en el la tabla
de datos para después insertarlos en la tabla interna del field catalog.

Se introduce la columan de la tabla para el campo fieldname. Este campo se utiliza para
asignar una columan field catalog a una columna de la tabla.

Los otros campos en el field catalog se pueden agrupar en dos grupos:


- Las referencias a tipos globales son creadas usando ref_field y ref_table.
- El resto de campos en el field catalog contienen valores para las caracteristicas
de columnas.
La informacion que se muestra en el ALV se gestiona a traves del metodo
set_table_for_first_display.

Añadiendo o modificando columnas

49
El field catalog se llena en el programa y se pasas con el nombre de la estructura del
dictionary durante la llamada al método. (Set_table_for_first_display)

Atributos de salida de una columna

COL_POS: para calcular la posición de la columna.


Emphasize: para dar notoriedad al campo.
No_out: esconder la columna.
Tech: la columna no se muestra en la lista o en los dialogs de selección de campos.

50
Atributos de Formato del contenido de columna
Estos son los formatos que se les pueden asignar a los campos:

51
ALV Grid Control - Layout
Se puede cambiar el layout de un ALV haciendo que las filas salgan de diferentes
colores, cambiando el ancho de columna etc….
Para ello se debe crear un work area <wa_layout> en el programa referenciando a la
estructura lvc_s_layo y rellenar los campos correspondientes.

Después hay que pasar el work area al parámetro is_layout del método
set_table_for_first_display.

LVC_S_LAYO es una estructura de tipo global que incluye los siguientes campos:

52
Dependiendo del valor que se selecciona en el sel_mode field en la estructura layout, el
usuario puede seleccionar líneas individuales o múltiples.

Los datos en el layout pueden ser ordenados por los usuarios dinámicamente. Para ello
hay que introducir una tabla interna en it_sort del método set_table_for_first_display.
Hay que utilizr el tipo lvc_t_sort para esta tabla.

En esta tabla interna, se tiene que insertar una linea por cada campo que se va a utilizar
como criterio de ordenación
-Introducir el nombre de columna en fieldname.
-Si se usa mas de un criterio de selección, hay que introducir la secuencia en la
que se va a evaluar el criterio de selección en el campo spos en cada caso.
Alternativamente se pueden insertar en la secuencia deseada en la tabla interna.
-Introducir X en el campo, si se desea ordenar las entradas en orden ascendente.

Colores de las filas y columnas

En el campo info_fname, hay que introducir el nombre del componente de la columna


color para una estructura del tipo global lvc_s_layo y pasar la estructura al parámetro
is_layout.

53
Se puede modificar el color de las lineas y las columnas.

CONCATENATE ‘C’ <color_constant> <intensified> <inverse> INTO wa_sbook-


color.

El valor del color está compuesto de cuatro componentes:


-Letra C.
-Número de uno de los 8 colores.
-1 intensified 0 no.
-1 inversion de color foreground y background, 0 no.

Escondiendo funciones estándar


Se pueden esconder las funciones Standard., la toolbar etc….

Dependiendo de la aplicación y los datos mostrados en el ALV Grid Control, solo unas
funciones se pueden utilizar.

Para ocultar funciones individuales, hay que definir una tabla interna ui_funcions. Hay
que llenar esta tabla interna con los nombres de las funciones que se quieren inactivar.
Estos posibles valores están disponibles como constantes de la clase cl_gui_alv_grid.
Todos los funtion codes tienen el prefijo MC_FC. El prefijo MC_MB representa un
menú enero en el toolbar.

Finalmente se le pasa la tabla al método set_table_for_first_display. Para desactivar


todas las funciones se puede usar la constante: MC_FC_EXCL_ALL.

Para ocultar la barra de herramientas entera, en el parámetro no_toolbar del layout se


pone X y se le pasa al método set_table_for_first_display.

54
ALV Grid Control - Eventos
Mediante alv se pueden capturar eventos, cuando se hace un doble clic sobre alguna de
las filas de la lista creada. El tratamiento es igual a los eventos donde habra un handler
que gestione el doble clic.

En el ejemplo de abajo, el evento doble clic es capturado utilizando un método handler.

Un método handler puede ser también un método de clase o una instancia de metodo de
un objeto. Si un método de clase se define como método handler, no se necesita
instanciar el objeto de la clase handling, para usar el método.

Para crear un objeto handler para un evento, hay que definir la clase. Esta clase tiene un
método público, en la sección pública que puede reaccionar al evento. En la
implementación del método handler, se crea el código fuente que va a ejecutarse cuando
se lance el evento. El método recibe la información por el evento desde la posición del
ratón cuando un usuario hace doble clic y en el ejemplo se genera un mensaje de
información que muestra la línea y el campo en el que se ha hecho clic con el ratón.

55
Unidad 5: EXCEPTION HANDLING
(CONTROL DE EXCEPCIONES) AND
RTTS
Exception handling en ABAP Objects
Class-Based Exception Handling
Usamos el término excepción para referirnos a una situación que surge mientras un
programa se está ejecutado, y surge un error. Las excepciones y el control de la
excepción están ahora basadas en clases.

Las class-based exceptions son lanzadas por la sentencia RAISE EXCEPTION o por
el entorno en tiempo de ejecución. La división por cero, por ejemplo, sería un ejemplo
de una excepción lanzada por el entorno en tiempo de ejecución.

En una situación de excepción, una excepción es representada por un exception object,


es decir, por una instancia de una exception class. Los atributos de cada exception
object contienen la información sobre la situación de error.

Cuando se controla una excepción, se puede lanzar nuevas excepciones y por tanto crear
una cadena de excepciones. En casos especiales, se puede capturar una excepción en
tiempo de ejecución y tener que lanzarla otra vez por su cuenta.

El usuario puede definir exception classes, pero ya hay un grupo predefinido en el


sistema, particularmente para excepciones del entorno en tiempo de ejecución.

Si una exception class es lanzada, el sistema interrumpe la ejecución y trata de ir a un


gestor (handler) apropiado. Si no puede encontrar un gestor, ocurre un error en tiempo
de ejecución.

Todas las exception class derivan de una de las classes CX_NO_CHECK,


CX_DYNAMIC_CHECK, o CX_STATIC_CHECK, las cuales derivan a su vez de la
superclass CX_ROOT .

56
La manera en la que las clases de excepción son asignadas a una de estas tres clases en
la jerarquía define cómo las associated exceptions son propagadas.
En el sistema estándar de SAP, los nombres de todas clases de excepción empiezan con
CX _.

Métodos que proporciona la clase de CX_ROOT:


• GET_SOURCE_POSITION: Devuelve el nombre del programa principal y (si
es importante) los nombres de los includes del programa y el número de línea en
el código fuente donde ocurrio la excepción.
• GET_TEXT: Devuelve un exception text en forma de un string.

Se puede asignar varios textos a cada clase. Los IDs asignados son creados por el Class
Builder como el mismo nombre que las constantes estáticas. Se puede especificar qué
texto se usa cuando una excepción es lanzada pasando una de estas constantes al
parámetro TEXTID de la instance constructor.
Todas las exception class heredan el atributo KERNEL_ERRID de CX_ROOT. Este
atributo contiene el nombre del error en tiempo de ejecución si la excepción fuera
lanzada por el entorno en tiempo de ejecución.

Las excepciones se controlan introduciendo la sentencia que la lanza en un bloque


TRY-ENDTRY. La excepción es controlada usando la instrucción CATCH en el
bloque TRY-ENDTRY

El bloque TRY contiene el conjunto de sentencias que manejan las excepciones. Si una
excepción ocurre en el bloque TRY, el sistema busca primero una sentencia CATCH
en el mismo bloque TRY-ENDTRY, y si no lo encuentra busca en los demás bloques
TRY-ENDTRY.

Un bloque CATCH contiene el exception handler (controlador de excepción) que se


ejecuta si una excepción específica ocurre en el bloque TRY asociado. Se puede
especificar cualquier número de exception class en la sentencia CATCH. De este modo,
se define un controlador de excepción para todas estas clases de excepción y sus
subclases.

57
Los bloques TRY, CATCH, y CLEANUP pueden contener a su vez bloques TRY-
ENDTRY.

Después de que ocurra una excepción, el sistema busca en una lista de exception
handlers en el orden especificado. Ejecuta el primer exception handler cuya sentencia
CATH contiene la exception class o uno de sus superclasses.

Un bloque CLEANUP se ejecuta si se sale del bloque TRY-ENDTRY, porque el


sistema no puede encontrar un controlador para una excepción dentro de dicho bloque
TRY-ENDTRY, pero la excepción es controlada en un siguiente bloque TRY-
ENDTRY o se propaga al programa que hizo la llamada (calling program).

Ejemplo: Controlando una excepción predefinida


Hay dos características especiales en el siguiente ejemplo. Primero, sólo se instancia
una clase de excepción estándar. Segundo, la excepción será lanzada por el sistema en
tiempo de ejecución como resultado de un error

En el cálculo anterior, si el valor para el tipo de datos I se supera, el sistema en tiempo


de ejecución lanza la excepción CX_SY_ARITHMETIC_OVERFLOW. Esta excepción
es controlada en el CATCH block. La referencia para la instancia apropiada es
almacenada en el objeto de datos REF_EXC. El controlador puede acceder a la instancia
de la excepción y usa el método GET_TEXT . El texto es almacenado en el data object
TEXT con el tipo STRING y luego se visualiza como un mensaje de información.

En la sentencia MESSAGE string TYPE message_type como el mensaje de STRING


será visualizado, también se debe especificar el message_type.

Si el rango de valores para el tipo de datos I (información) no se supera, ninguna


excepción es lanzada y el TRY block es procesado completamente.

La clase CX_SY_ARITHMETIC_OVERFLOW es una subclase de las classes


CX_SY_ARITHMETIC_ERROR, CX_DYNAMIC_CHECK, y CX_ROOT. Por lo
tanto, la excepción lanzada anteriormente también puede ser controlada si se introduce
en una de estas clases después del CATCH.

58
Éste es un ejemplo sencillo. Normalmente, se define con tipo numérico F para evitar un
error en tiempo de ejecución.

Defininir Global Exception Classes


1. In the Class Builder, crear una clase global en la biblioteca de SAP. Usar el prefijo
CX _ para el nombre. Elegir la opción Exception Class como Class Type. No
cambiar el valor de entada por defecto Inherits from superclase.

2. Si es necesario dar atributos adicionales a la exception class.


Si estos atributos son públicos, el Class Builder genera un constructor apropiado a
fin de que los valores se puedan establecer cuando la excepcion sea lanzada. Los
parámetros import son generados con los mismos nombres que los atributos.

3. Guardar tantos exception text como se necesiten. Se puede insertar sus atributos
como parámetros en el static text de la forma &<attribute_name>&.
Para el primer texto que se crea, usar siempre una constante estática como un ID.
Si no hay texto especificado explícitamente cuando la excepción se lanza, el texto
con esta ID es usado en su lugar. Para todos los demás textos, defina otros ID. El
Class Builder genera las constantes estáticas nombrándolas automáticamente.
Cuando la excepción es lanzada, se pasa una de estas constantes al parámetro
TEXTID para especificar el texto apropiado para la excepción.

4. Activar la exception class.

Propagar y controlar una excepción


Las excepciones que ocurren en los procedimientos no necesitan ser controladas donde
ocurren; pueden ser propagados al que llamo al procedimiento. Los niveles más altos a
los que una excepción puede ser propagada son processing blocks sin áreas de datos
locales, es decir los event block o los dialog modules.

Para propagar una excepción desde un procedimiento, se usa RAISING cuando se está
definiendo la interfaz del procedimiento. En los métodos de clases locales y subrutinas,
especifique el RAISING directamente cuando se está definiendo el procedimiento:

METHODS meth_name ... RAISING cx_... cx_... or

FORM subr_name ... RAISING cx_... cx_....

Después del RAISING, ponga en una lista las exception class cuyas insntacinas van a
ser propagadas. En los métodos de las clases globales, las exception class cuyas
instancias son propagadas son introducidas en la exception table del metodo en el Class
Builder. Es necesario activar el flag Exception Class para cada exception table. Escoger
el Exceptions tab.

El parámetro de TEXTID es opcional. El valor por defecto es siempre la constante


estática, que tiene el mismo nombre que la exception class. Sin embargo, una de las
constantes estáticas definidas como text IDs en la exception class también puede ser
usada para proporcionar el valor. Cuando la excepción es lanzada, el texto apropiado

59
para esa excepción es lanzada. Después de que la excepción ha sido captada, se puede
visualizar el texto usando el método GET_TEXT.

Si el que llama no captura la excepción, puede ser pasado hacia arriba al siguiente nivel
llamador. Antes de que el control sea pasado al próximo llamador, el bloque opcional
CLEANUP puede ser ejecutado.

Ejemplo: Raising, Propagating and Handling an Exception


CLASS lcl_plane DEFINITION.

PUBLIC SECTION.
...
METHODS get_attributes
EXPORTING
ex_name TYPE t_name_15
value(ex_wa_plane) TYPE saplane
RAISING
cx_bc401_excd_planetype.

ENDCLASS. "lcl_plane DEFINITION

CLASS lcl_plane IMPLEMENTATION.


...
METHOD get_attributes.
SELECT SINGLE * FROM saplane
INTO ex_wa_plane
WHERE planetype = me->type.
IF sy-subrc = 0.
IF ex_wa_plane-seatsmax_b= 0. "should stand for freighter here
RAISE EXCEPTION TYPE cx_bc401_excd_planetype
EXPORTING
planetype = me->type
textid = cx_bc401_excd_planetype=>cx_bc401_excd_planetype_f.
ENDIF.
ELSE.
RAISE EXCEPTION TYPE cx_bc401_excd_planetype
EXPORTING
planetype = me->type.
ENDIF.
ENDMETHOD. "lcl_plane
ENDCLASS. "lcl_plane IMPLEMENTATION

CLASS lcl_carrier DEFINITION.


PUBLIC SECTION.
...
METHODS display_attributes.
ENDCLASS. "lcl_carrier DEFINITION

CLASS lcl_carrier IMPLEMENTATION.


...
METHOD display_attributes.
DATA:
l_ref_plane TYPE REF TO lcl_plane,
l_name TYPE t_name_15,
l_wa_plane TYPE
saplane,

l_ref_exc TYPE REF TO cx_bc401_excd_planetype,


l_exc_text TYPE string.
...
TRY.
CALL METHOD l_ref_plane->get_attributes
IMPORTING
Ex_wa_plane = l_wa_plane.
CATCH cx_bc401_excd_planetype INTO l_ref_exc.
L_exc_text = l_ref->get_text().
WRITE l_exc_text COLOR COL_NEGATIVE.
ENDTRY.
ENDMETHOD.
ENDCLASS.

60
Class-Based Exceptions en Debugging Mode
Si una excepción es lanzada, el nombre de la exception class es mostrado en el campo
Exception Raised en el debuggin mode.

Si esta excepción es capturada en el bloque CATCH, esto se muestra en un mensaje. El


puntero de la instrucción en curso cambia de lugar al bloque CATCH.

Aparecen dos botones. Esto botones permiten mostrar los valores de los atributos de la
excepción y navegar al punto del código fuente donde ocurrió la excepción.

Exception Classes: The Inheritance Hierarchy


A continuacion se explica las consecuencias que surgen de la elección de una excpecion
de la clase superclase.

En la subclases de CX_STATIC_CHECK, la excepción mas importante deben ser


tratada o propagada explícitamente usando el RAISING. Si éste no es el caso, el syntax
check visualiza un warning.

La regla para las subclases de CX_STATIC_CHECK también es aplicable a las


subclases de CX_DYNAMIC_CHECK. Se debe controlar o propagar usando
explícitamente RAISING. La diferencia es que esto no es chequeado estáticamente, no
se muestra ningún warning si no se trata o propaga la excepción. Si la excepción se
lanza, se produce un error en tiempo de ejecución.

Para las subclases de CX_NO_CHECK, la regla es que las excepciones


correspondientes no pueden ser propagadas explícitamente usando RAISING. Estas
excepciones pueden ser controladas. Por lo demás, son propagadas automáticamente.
No se muestra ningun syntax warning en tiempo de ejecución dónde se lanzan. En su
lugar, todas las excepciones que no son controladas en alguna parte en la jerarquía son

61
propagadas hasta el nivel de llamada más alto. Si no es capturada allí tampoco, se
produce un error en tiempo de ejecución Algunas excepciones predefinidas con el
prefijo CX_SY _.... son subclases de CX_NO_CHECK.

Mapear una excepción en otra


Para tener claridad, se debe comprender que una excepción puede ser propagada a
través de cualquiera de las jerarquías antes de que ser controlada definitivamente.

El lanzamiento de diferentes excepciones puede ser conectado o encadenado (chained).


Una excepción puede lanzar una segunda, etcétera. Cada instancia debe mantenerse,
teniendo en cuenta o no el bloque CATCH que esta a la izquierda. Hay que asegurarse
de que la exception instance previa pueda ser accedida siempre mediante al menos una
referencia. El atributo públicos PREVIOUS, hereda todo de la exception class
CX_ROOT, que proporciona una manera conveniente de hacer esto.

Cuando se lanza la siguiente excepción, solo se debe pasar una referencia a la excepción
anterior a la nueva instancia. Esto se hace con el parámetro opcional PREVIOUS del
constructor. De este modo, la nueva excepción es mapeada a la anterior. Después de
que la excepción mapeada ha sido capturada, el atributo PREVIOUS contiene una
referencia a la instancia de excepción previa, etcétera. De este modo, se puede acceder a
cada instancia en la cadena de excepciones. Por lo tanto, se puede seguir la historia del
lanzamiento de las excepciones en el programa.

Ejemplo: Crear una cadena de excepciones


CLASS lcl_carrier DEFINITION.
PUBLIC SECTION.
...
METHODS display_attributes
RAISING cx_bc401_excd_list.

ENDCLASS. "lcl_carrier DEFINITION

CLASS lcl_carrier IMPLEMENTATION.


...
METHOD display_attributes.

62
DATA:
l_ref_plane TYPE REF TO lcl_plane,
l_name TYPE t_name_15,
l_wa_plane TYPE saplane,

l_ref_exc TYPE REF TO cx_bc401_excd_planetype,


l_exc_text TYPE string.
...
TRY.
CALL METHOD l_ref_plane->get_attributes
IMPORTING
ex_wa_plane = l_wa_plane.
WRITE: l_wa_plane-planetype,
l_wa_plane-producer,
l_wa_plane-seatsmax_b.
CATCH cx_bc401_excd_planetype INTO l_ref_exc.
l_exc_text = l_ref_exc->get_text( ).
WRITE l_exc_text COLOR COL_NEGATIVE.
RAISE EXCEPTION TYPE cx_bc401_excd_list
EXPORTING
previous = l_ref_exc.
ENDTRY.
ENDMETHOD. "display_attributes
ENDCLASS. "lcl_carrier IMPLEMENTATION
...
DATA:
ref_plane TYPE REF TO lcl_plane,
ref_carrier TYPE REF TO lcl_carrier,
ref_exc TYPE REF TO cx_bc401_excd_list,
exc_text TYPE string,
previous_text TYPE string.
...
START-OF-SELECTION.
...
TRY.
CALL METHOD ref_carrier->display_attributes.
CATCH cx_bc401_excd_list INTO ref_exc.
exc_text = ref_exc->get_text( ).
MESSAGE exc_text TYPE ’I’.
previous_text = ref_exc->previous->get_text( ).
MESSAGE previous_text TYPE ’I’.
ENDTRY.
...

RTTI (Run Time Type Service)


RTTI/ Type Analysis at Runtime
En objetos de ABAP, hay un concepto de clase llamado Run Time Type Information
(RTTI) que se puede usar para determinar los atributos en tiempo de ejecución. Este
concepto incluye todos tipos de ABAP.

Hay una description class para cada tipo con atributos especiales.

La jerarquía de clases de las description class corresponde a la jerarquía de tipos de


ABAP Objects. Además, las description class para tipos complejos, referencias, clases,
e interfaces tienen métodos especiales que se usan para especificar referencias a
subtipos. Se puede usar estos métodos para navegar a través de un tipo compuesto a
todos sus subtipos.

Para obtener una referencia a un description object de un tipo, se debe usar los métodos
estáticos del class CL_ABAP_TYPEDESCR o los métodos de navegación de la
description class especial. Los description objects son creados de una de las subclases.

63
En tiempo de ejecución, un description object existe para cada tipo. Los atributos del
objeto de descripción contienen la información sobre los atributos del tipo.

Métodos y atributos de la Root class

Dynamic Data Type Analysis: Ejemplo de aplicación


En el siguiente ejemplo, los atributos de una estructura son identificados usando RTTI.
La subclase CL_ABAP_STRUCTDESCR se usa para este propósito.

Debido a que se necesita los atributos de una estructura, se debe definir una referencia
primero a la description class apropiada. Las instancias de esta clase tienen un atributo
COMPONENTS que se usa para describir los componentes individuales de la
estructura. Este atributo es una tabla interna. Por lo tanto, también tiene que definir una
work area con un line type compatible.

64
El método llamado devuelve la referencia para la description instance de la estructura
transferida.

La clase abstracta CL_ABAP_TYPEDESCR contiene el método estático


DESCRIBE_BY_DATA. Este parámetro RETURNING es declarado como una
referencia a esta superclass. Sin embargo, debido a que el actual parámetro R_DESCR
es declarado en la subclase CL_ABAP_STRUCTDESCR, el objeto tiene que ser
asignado usando un widening cast.

Se puede acceder a los atributos de la instancia de descripción de cualquier forma. En


este ejemplo, los nombres componentes son mostrados como las cabeceras de los
campos.

Dynamic Object Type Analysis: Ejemplo de aplicación


En el siguiente ejemplo, los atributos de un objeto son analizados. Muestra la referencia
SENDER del método ADD_VEHICLE para la clase LCL_RENTAL.

65
Como ejemplo, se debe ampliar la aplicación existente con la agencia de viajes y su
socio comercial.

En el anterior ejemplo, se especifico que una instancia de la LCL_RENTAL reaccione


frente a un evento incluyendo la instancia del vehículo que provocó el evento en la lista
de vehículos VEHICLE LIST. Hasta ahora, las instancias podían ser autobuses
(LCL_BUS) o camiones (LCL_TRUCK).

La referencia para la instancia de vehículo es contenida en el parámetro SENDER


método de evento mencionado anteriormente. Este type object dinámico ha de ser
analizado para determinar si el vehículo en cuestión es un autobús o un camión.

Un método de RTTI llamado devuelve la referencia para la description instance de la


instancia de vehículo transferido.

La clase abstracta CL_ABAP_TYPEDESCR tiene su método DESCRIBE_BY_OB-


JECT_REF. Su returning parameter es declarado como una referencia a esta superclass.
Sin embargo, debido a que el actual parameter R_DESCR esta declarado en la subclase
CL_ABAP_CLASSDESCR, el objeto tiene que ser asignado usando un widening cast.

Se puede acceder a los atributos de la instancia de descripción de cualquier forma. El


método funcional GET_RELATIVE_NAME proporciona el nombre de clase.

También se puede hacer lo mismo sin usar clases de RTTI. Por ejemplo, se puede usar
una asignación widening cast del SENDER a una variable de referencia que tenga un
tipo estático LCL_BUS. Esto daría un error en tiempo de ejecución para instancias de
vehículo que no son buses. El sistema podría capturar este error en tiempo de ejecución.
Por lo tanto, un error en tiempo de ejecución no se provoca siguiendo el criterio de
incluir un vehículo en la lista de vehículos.

RTTC/ Type Creation at Runtime


Las clases de tipo de RTTI fueron creadas para facilitar la creación de tipos en tiempo
de ejecución.

Las propiedades de los tipos son implementadas por type-object attributes. Esto quiere
decir que cada tipo tiene uno type object cuyos atributos describen las propiedades del
tipo.

La jerarquía de clases de las type classes corresponde a la jerarquía de tipos en el


sistema de tipos de ABAP. Los type objects pueden ser creados por los métodos de la
type class. Para obtener referencias a los type objects, se puede llamar a los métodos
estáticos de la clase CL_ABAP_TYPEDESCR o métodos de las clases de tipo
especiales (GET_I, GET_C, CREATE).

66
Un tipo es definido completamente por su type object.
• Hay un runtime type object para cada tipo.
• El runtime type object describe el data type totalmente.
• Un type object esta definido en un programa local y es transitorio y anonimo.
• No se puede eliminar o cambiar un type object.

Se puede usar RTTC para crear tipos de datos básicos. Sin embargo, también se puede
usar para crear tipos de datos más complejos como estructuras o tablas internas.

La pregunta que surge ahora qué debe hacerse con el tipo de tabla que acaba de ser
creado. Por ejemplo, se pude usar el codigo siguiente como ejemplo de creación de una
tabla interna en tiempo de ejecución:
...
DATA r_itab TYPE REF TO data,
r_tableType TYPE REF TO cl_abap_tabledescr.
...
* Creation of internal tabletype with static method
* CREATE of RTTS-class cl_abap_tabledescr
...
CREATE DATA r_itab TYPE HANDLE r_tabletype.

Usando HANDLE con la sentencia CREATE DATA se crea una tabla interna cuyos
tipos son descritos por un RTTS type objects. El type object puede ser creado usando
los métodos de RTTS o definiendo dinámicamente un nuevo data type.

67
Unidad 6: Objetos compartidos
Introducción
Desde la versión 6.40 se pueden guardar datos como objetos compartidos en la memoria
compartida, para diferentes programas y sesiones de usuario. Se pueden crear
aplicaciones en las que los usuarios escriben datos en este área. Otros usuarios pueden
después leer estos datos.
Se pueden imaginar muchos y diferentes usos potenciales para los objetos compartidos:
-Guardar catálogo: Un autor escribe el catálogo en el area de objetos compartidos y
otros usuarios lo leen.
-Guardar Shopping cart: El comprador llena el shopping cart y el vendedor lo lee
posteriormente.

Memoria compartida
Área de memoria que puede ser accedida por todos los programas ABAP ejecutándose
en ese servidor.

Antes de que existieran los objetos compartidos se usaban las sentencias IMPORT y
EXPORT con los parámetros SHARED BUFFER y SHARED MEMORY para acceder
a esta área de memoria. Las instancias de clases “vivían” exclusivamente en la internal
session de un programa ABAP. La memoria compartida se ha mejorado con la
memoria compartida de objetos, donde los objetos compartidos se pueden guardar. Los
objetos compartidos son almacenados en llamadas áreas de memoria compartida.

68
Propiedades de los objetos compartidos
Buffers compartidos por varias aplicaciones que se leen mucho y se escriben poco (la
escritura consume muchos recursos).
Accesos concurrentes de lectura son soportados.
El acceso es controlado por un mecanismo de bloqueo.
Los datos se guardan como atributos de los objetos.
Los cuellos de botella de la memoria provocan errores en tiempo de ejecución que
necesitan ser capturados (con un catch).
Un prerrequisito para guardar un objeto en la memoria compartida es que la clase de ese
objeto tiene que estar definida con el parámetro SHARED MEMORY ENABLED en la
definición de la clase o que el atributo Shared memory enabled está marcado en el Class
Builder.

Áreas e Instancias de área

Un área es una (template) plantilla para las instancias de area en una memoria
compartida. Un área puede contener varias instancias de áreas, las que difieren en el
nombre. Además una instancia de área puede tener varias versiones, los cuales difieren
en la ID de la versión. En el caso más simple, sin gestión de versiones, una instancia de
área consiste en una única versión de instancia de área.

Area classes y Area handles

En la transacción SHMA se define un área. Esto crea una clase de área global, final
que hereda de CL_SHM_AREA. Un área es accedido exclusivamente usando los
métodos de la clase de área generada.

69
Convención de nombres para clases → ZCL_*
Se pueden utilizar métodos estáticos de una clase de área para añadir un programa de
ABAP a una instancia de área en la memoria compartida.
En el diagrama de arriba se puede ver otra clase, que se llama area root class. Se puede
crear cualquier número de objetos en una instancia de área, dependiendo del programa
específico. Se accede a estos objetos uniformemente a través de la instacia de area root
class.

Aplicación de ejemplo

Crear una lista de fechas de vuelos, para que los usuarios seleccionen más rápido el
vuelo.

Situación: 2 aplicaciones en sesiones diferentes acceden a objetos en la mismo área.


Para ello es necesario:
 Crear un área.
 Desarrollar un programa que cree una instancia de un área.
 Desarrollar un programa que lea datos del área.

Crear un área
Los objetos compartidos son guardados en áreas de la memoria compartida. Usar la
transacción SHMA para crear y modificar áreas y sus atributos.

70
¡OJO!: la transacción SHMA no está en el árbol del menú → hay que teclearla arriba.
Se llama a la transacción SHMA y se introduce el nombre del área. El nombre del área
debe empezar por Z o por Y.
En programas ABAP, el area será accedido después utilizando exclusivamente los
métodos generados de la clase de área.

Después de presionar crear, cambiar o visualizar, la pantalla de mantenimiento para las


áreas aparece.
Todas las áreas están ligadas a una clase de área maestra (‘area root class’) global cuyos
atributos contienen datos propietarios y referencias a otras clases con una memoria
compartida habilitada. Hay que asignar el area root classs al área cuando se mantiene.
Al generar un área se inserta en el código un atributo raíz (‘root’) declarado como un
tipo estático de clase de área maestra (‘area root class’).

Otros aspectos a tener en cuenta al crear un área


Área dependiente del cliente (‘client-dependent area’)
Las áreas y sus objetos no tienen un identificativo de cliente por defecto. Sin embargo
se pueden especificar un area como dependiente de cliente.
En áreas dependientes del cliente, los métodos de la clase ‘área’ para acceder una
instancia de un área se refieren por defecto al cliente activo. Se puede utilizar el
parámetro importing CLIENT opcional para acceder a otro cliente explícitamente.
Área transaccional
Una instancia de un área de un área transaccional no se activa inmediatamente después
de liberarse la protección de escritura con el método DETACH_COMMIT; no se activa
hasta el siguiente envío a la BD (commit).
Esto es muy útil en la implementación de shopping carts en la memoria de objetos
compartidos.

Crear la instancia de un área


Previamente se ha creado el área y las clases que van a ser instanciadas en esa área.
Ahora se van a exponer las instrucciones para crear la instancia del área.

71
Cuando se crea un área, se crea también una clase global final del mismo nombre.
Necesitamos ahora una variable de referencia que esté declarada en esa clase. Esta
referencia sirve de handle para acceder al área.

Cuando se instancia la clase ‘área’, se crea una instancia de la clase en la memoria


compartida. El programa tiene un andel para esta instancia del área; todas las futuras
operaciones se realizan utilizando este handle.

72
Una vez que se ha creado la instancia, ya se puede crear objetos en la memoria
compartida → añadir el parámetro AREA HANDLE en la sentencia de declaración
CREATE OBJECT.

En la figura de arriba, ambos objetos son instanciados desde el programa.


Alternativamente se puede instanciar el objeto root desde el programa. Los otros objetos
en esta área se pueden crear después desde el constructor del objeto root.
No hay que asignar las referencias en este caso.

73
Para permitir llamar a los objetos creados en área de instancia, hay que asignar el objeto
root al atributo ROOT del area handle. Para hacer esto, se utiliza el metodo SET_ROOT
de la area handle.
Como consecuencia cualquier programa de la aplicación puede acceder a esta área.

El permiso de lectura no existe hasta que se ha quitado la protección de escritura. Se usa


el método DETACH_COMMIT que hace que la clase ‘área’ herede de
CL_SHM_AREA.

Accediendo a una instancia de un área


Una vez esto, cualquier programa de cualquier aplicación puede acceder a esta área.Los
programas que vayan a leer deben seguir los siguientes pasos:

74
El programa de lectura necesita una variable de referencia declarada con la clase ‘área’.
Este variable de referencia sirve como instancia del área al que se quiere acceder.
El programa también necesita el handle de esta instancia del área. Esto se hace con el
método ATTACH_FOR_READ de la clase CL_SHM_AREA. Así se establece un
bloqueo de lectura (‘read lock’) que evita escrituras durante el acceso.
Los objetos en esta área se pueden acceder ahora con el area handle. El seguro de
lectura se libera automáticamente al cerrar la sesión o con la instrucción DETACH.

Estados de una instancia de área


Cuando se crea un nuevo area, existen varias versiones temporales de la misma
instancia concurrentemente.
Mientras se configura:
Cuando una aplicación pone un cierre de lectura a una instancia, una versión temporal
se crea de forma paralela a la versión activa.

75
Si el atributo number of versions del area está configurado apropiadamente, versiones
adicionales de la instancia del area pueden existir además de la versión activa.
Cuando un nuevo catalogo se esta configurando, varias versiones temporales de la
misma instancia de area existen concurrentemente. Tan pronto como una aplicación
pone un bloqueo de cambio para una instancia de área, se crea una “versión que se esta
configurando” y existe en paralelo a la versión activa.
Versión descatalogada (‘outdated’):

Si la configuración de la nueva versión se completa antes de que finalice la lectura, la


versión que se acaba de configurar se convierte en activa. La versión activa pasa a ser
outdated.

76
El seguro de lectura sobre el fichero descatalogado permanece hasta que todas las
operaciones de lectura han acabado. Si hay nuevas lecturas sobre la instancia ‘área’ se
producen sobre la versión activa. Pueden existir por tanto dos lecturas distintas al
mismo tiempo.
Versión caducada (‘expired’):

Cuando se ha terminado de leer el último bloque de una instancia descatalogada, la


instancia caduca y es eliminada por el recolector de basura (‘garbage collector’).

77
Nuevas protecciones de lectura (‘read locks’) se aplican solo a la versión activa. Solo
puede haber una versión activa de una instancia. Dependiendo del número máximo de
versiones, aún pueden existir versiones descatalogadas en la que queden todavía bloques
por leer.

78
Unidad 7: Caso de estudio
Caso de estudio (ejemplo)
Los programas que se van a crear deben dar al usuario una pantalla que controle a los
clientes que utilizan listas de vuelos. Debería ser posible mantener una lista de espera
para cada vuelo (fila de la tabla SFLIGHT con las claves CARRID, CONNID y
FLDATE).
Todas las listas se almacenan en un buffer llamado WAIT_LIST (una tabla interna).
Además de la información del vuelo las listas de espera deben contener todos los
clientes registrados para este vuelo.
Las funciones de la aplicación se muestran en la siguiente figura:

La pantalla y las funciones aquí mostradas deben ser creadas de acuerdo a las
especificaciones requeridas.
Los requisitos contienes funciones como:
 Mostrar : waiting list para el vuelo señalado
 Crear : crea una lista de espera para el vuelo señalado
 Borrar (listas de espera)
 Añadir : Añade el cliente seleccionado en la pantalla de la derecha al witing list del
vuelo de la derecha.
 Borrar (clientes): Cliente de la derecha de la lista de vuelos del vuelo de la
izquierda.
 Posición (en la lista de espera) : Muestra la posición cliente seleccionado en la lista
de espera.

79
Objetos compartidos
Se pueden utilizar desde la versión 6.40 de SAP Web AS.
Utilidades:
 Cesta de la compra: el comprador rellena la cesta que la lee luego el dependiente.
 Catálogo: muchos usuarios acceden simultáneamente a la misma información.
Para que un programa de ABAP pueda acceder hay que utilizar las sentencias EXPORT
e IMPORT con los parámetros SHARED BUFFER o SHARED MEMORY.
Con la introducción de objetos compartidos la memoria compartida pasa a ser una
memoria compartida de objetos.

Prerrequisitos de los objetos compartidos


 Pocas escrituras y muchas lecturas.
 Soportar multiaccesos de lectura.
 El acceso es regulado con un mecanismo de protección (‘lock’).
 Los objetos de datos que están referenciados utilizando referencias a datos no se
pueden almacenar directamente.
 Los cuellos de botella provocan errores en tiempo de ejecución que deben ser
capturados.
Las áreas (zonas compartidas de memoria) se crean y modifican en la transacción
SHMA.Para crear un área compartida se debe cumplir una de estas dos condiciones:
-Añadir el parámetro SHARED MEMORY ENABLED en la declaración de la clase.
-Activar el atributo “shared memory enabled” en el class builder (programa para crear
clases).
Cada área es vinculada con una clase global raíz (root). Cada área sirve de plantilla para
instancias del área en la memoria compartida.
Cuando se define un área una clase global final con el mismo nombre se crea como
subclase de CL_SHM_AREA.
En un programa en ABAP, se accede a un área con los métodos exclusivos de esa clase.
Hay métodos estáticos que se añaden al programa en ABAP, a instancias de áreas en la
memoria compartida.

80
Con adjuntos (programas de ABAP añadidos a la memoria compartida), se crea una
instancia de clase ‘área’ como area handle y se establece al mismo tiempo una
protección contra escritura. (‘read lock’).El programa en ABAP puede utilizar el area
handle para acceder a la instancia del área añadida y por tanto a los objetos compartidos
allí almacenados. El area handle también contiene los métodos para liberar el cierre de
lectura.

ABAP Unit
Es una herramienta para crear clases de prueba. Esta integrada en el entorno de
desarrollo de ABAP (‘ABAP runtime enviroment’). Comprueba la funcionalidad del
código de un programa (módulos de tests).
Los módulos de prueba son en ABAP y van integrados en el método que se va a testear
→ son locales por lo que no hay problemas de versiones o transporte.
Estos módulos de prueba no afectan al rendimiento del sistema de producción.

81
-Estos test se programan en ABAP Objects.
-La test function esta contenida en los test methods de las test clases.
-Estas test clases estan contenidas localmente en el programa que se quiere testear. Esto
quiere decir que no hay transportes o problemas de verisiones.
-Si ocurre un error, el resto del procedimiento de testeo se puede controlar.
-El código de test no tiene efecto en producción.
-ABAP Unit no afecta al sistema de producción.

82