Los métodos de una clase definen su comportamiento y permiten modificar su estado. Al igual que los atributos, disponemos de dos tipos de métodos: Métodos de instancia y métodos estáticos.
- Métodos de instancia: estos métodos pueden acceder a todos los atributos de una clase y pueden disparar todos los eventos la misma.
- Métodos estáticos: Solo pueden acceder a los atributos estáticos, que si recordamos, son aquellos que definen de la forma CLASS-DATA, y que mantienen un único valor para todas las instancias activas de una clase. Además, pueden desencadenar los eventos estáticos de la clase.
A continuación, podemos ver un ejemplo de declaración de dos métodos de instancia y un método estático:
CLASS zcl_pedido DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
DATA cantidad_pedido TYPE i.
CLASS-DATA: cantidad_total TYPE i.
"Métodos estáticos
CLASS-METHODS: get_cantidad_total.
"Métodos de instancia
METHODS: anyadir_cantidad IMPORTING iv_cantidad TYPE i.
METHODS: get_cantidad_instancia.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
Para este ejemplo, vamos a crear una clase Pedido. Esta clase tiene dos atributos: un atributo que indica la cantidad del pedido, de tipo instancia, y un atributo estático que muestra la cantidad total de todos los pedidos instanciados en este momento. Para la definición de los métodos, utilizamos la palabra reserva METHODS para definir el método de instancia que añadirá cantidad al pedido y sumará a la cantidad total de todos los pedidos, y para el método que recupera el valor de la cantidad del pedido; por otro lado, utilizamos la palabra reservada CLASS-METHODS para definir el método estático que obtendrá el valor del atributo estático cantidad_total que representa la cantidad total añadida a todos los pedidos activos.
Para poder comprobar el funcionamiento en ejecución de los dos tipos de métodos, definimos en la sección CLASS DEFINITION la lógica de ambos métodos. Destacar que no es necesario indicar la firma de nuestro método en su definición.
CLASS zcl_pedido IMPLEMENTATION.
METHOD get_cantidad_total.
IF cantidad_total EQ 0.
WRITE 'El pedido aún no tiene cantidad'.
ELSE.
WRITE: cantidad_total.
ENDIF.
ENDMETHOD.
METHOD get_cantidad_instancia.
WRITE cantidad_pedido.
ENDMETHOD.
METHOD anyadir_cantidad.
cantidad_pedido = cantidad_pedido + iv_cantidad.
cantidad_total = cantidad_total + iv_cantidad.
ENDMETHOD.
ENDCLASS.
Una vez definidos los métodos, donde simplemente implementamos una lógica muy sencilla para sumar cantidades y pintar por pantalla sus valores, crearemos un programa de tipo REPORT para comprobar el comportamiento de los dos tipos de atributos y para ver como crear los objetos de instancia y llamar a sus métodos desde un programa. Primero, adjunto la clase al completo, y en segunda lugar, el código del programa que ejecutaremos.
CLASS zcl_pedido DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
DATA cantidad_pedido TYPE i.
CLASS-DATA: cantidad_total TYPE i.
"Métodos estáticos
CLASS-METHODS: get_cantidad_total.
"Métodos de instancia
METHODS: anyadir_cantidad IMPORTING iv_cantidad TYPE i.
METHODS: get_cantidad_instancia.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_pedido IMPLEMENTATION.
METHOD get_cantidad_total.
IF cantidad_total EQ 0.
WRITE 'El pedido aún no tiene cantidad'.
ELSE.
WRITE: cantidad_total.
ENDIF.
ENDMETHOD.
METHOD get_cantidad_instancia.
WRITE cantidad_pedido.
ENDMETHOD.
METHOD anyadir_cantidad.
cantidad_pedido = cantidad_pedido + iv_cantidad.
cantidad_total = cantidad_total + iv_cantidad.
ENDMETHOD.
ENDCLASS.
*&---------------------------------------------------------------------*
*& Report zreport_pedido
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zreport_pedido.
DATA go_pedido TYPE REF TO zcl_pedido.
"La forma clasica de definir un objeto seria con CREATE OBJECT go_pedido |
" En este ejemplo, aprovechamos para ver el uso de NEW ABAP
go_pedido = NEW #( ).
DATA(go_pedido_2) = NEW zcl_pedido( ).
go_pedido->anyadir_cantidad( 10 ).
go_pedido_2->anyadir_cantidad( 30 ).
go_pedido->get_cantidad_instancia( ).
go_pedido_2->get_cantidad_instancia( ).
go_pedido->get_cantidad_total( ).
go_pedido_2->get_cantidad_total( ).
Lo primero que debemos hacer es crear el objeto. Con la entrada del NEW ABAP (veremos en detalle en otros artículos que cambios y mejoras aportan al ABAP clásico) podemos crear las instancias de los objetos de diferentes formas. La forma clásica de crear un objeto en ABAP es definiendo la referencia a nuestra clase, con la instrucción:
DATA go_pedido TYPE REF TO zcl_pedido.
CREATE OBJECT go_pedido.
De esta forma, creamos un objeto a partir de la referenciación que hemos asignado a la variable go_pedido. Con New ABAP, podemos crear el objeto de las dos formas distintas que vemos en el código de ejemplo:
DATA go_pedido TYPE REF TO zcl_pedido.
go_pedido = NEW #( ).
DATA(go_pedido_2) = NEW zcl_pedido( ).
O bien creamos la referencia a la clase y, posteriormente, creamos el objeto con la instrucción NEW #( ) ; o bien, creamos todo en una única línea de código creando la variable al mismo tiempo que le asignamos la creación del objeto, indicando en este caso el nombre de la clase junto con la palabra reservada NEW. Esta instrucción llama al método de construcción de una clase, que puede no tener parámetros (como en este caso) o podría tener una firma con parámetros que se pasarían entre los paréntesis.
Una vez creadas las instancias, ejecutamos los métodos de nuestra clase. Para ello, utilizamos → para acceder a aquellos atributos y métodos que son visibles desde fuera de la clase, es decir, aquellos atributos y métodos públicos (definidos en la PUBLIC SECTION).
go_pedido->anyadir_cantidad( 10 ).
go_pedido_2->anyadir_cantidad( 30 ).
go_pedido->get_cantidad_instancia( ).
go_pedido_2->get_cantidad_instancia( ).
go_pedido->get_cantidad_total( ).
go_pedido_2->get_cantidad_total( ).
En el código podemos observar que se han creado dos instancias de nuestra clase ZCL_PEDIDO: el objeto go_pedido y el objeto go_pedido_2. Para cada uno de ellos, se ha ejecutado el método anyadir_cantidad, indicando una cantidad diferente para cada instancia. Por último, se ejecuta para cada objeto el método que recupera la cantidad del pedido (actual) get_cantidad_instancia, y el método que recupera la cantidad total del pedido, get_cantidad_total. Con esto, la idea es comprobar como se comportan los atributos según el tipo que son. Si ejecutamos este código, obtenemos el siguiente resultado:

Para el objeto 1, se ha añadido un cantidad de valor 10; para el objeto 2, se ha añadido una cantidad de 30. Tras la ejecución del programa, observamos que efectivamente la variable cantidad_pedido tiene un valor distinto para cada objeto. ¿Pero qué sucede cuando para cada objeto recuperamos el valor del atributo cantidad_total?. Como mencionamos en el anterior artículo, los atributos estáticos comparten el MISMO valor para todas las instancias de la clase, por lo que no se guarda un valor distinto para cada instancia.
En conclusión, hemos descrito los dos tipos de métodos que existen y como definirlos. Además, hemos descrito las diferentes formas de creación de un objeto, ya sea con ABAP clásico o haciendo uso de las instrucciones del New ABAP. Por último, hemos accedido a los métodos de nuestra clase y hemos visto como se comportan ambos tipos de atributos. Recordad, que hemos podido acceder a los métodos desde un programa externo ya que están definidos en la PUBLIC SECTION.