En el ejercicio anterior, creó una clase superior común LCL_FLIGHT para las clases LCL_PASSENGER_FLIGHT y LCL_CARGO_FLIGHT. Ahora modificará la clase local LCL_CARRIER para utilizar la relación de herencia. Introducirá las variables de referencia utilizadas como parámetros para el tipo de la clase superior y, en lugar de dos atributos de instancia separados, pasajer_flights y cargo_flights, definirá un único atributo de instancia en el que puede almacenar referencias a todas las instancias de vuelo, independientemente de si son vuelos de pasajeros o de carga.
Tarea 1: Copiar plantilla (opcional)
Copie la clase de modelo /LRN/CL_S4D401_OOS_INHERITANCE. Si ha finalizado el ejercicio anterior, puede omitir esta tarea y continuar editando su clase ZCL_##_SOLUTION.
Pasos
Copie la clase /LRN/CL_S4D401_OOS_INHERITANCE en una clase de su propio paquete (nombre sugerido: ZCL_##_SOLUTION, donde ## representa su número de grupo).
En el Explorador de proyectos, haga clic con el botón derecho en la clase /LRN/CL_S4D401_OOS_INHERITANCE para abrir el menú contextual.
En el menú contextual, seleccione Duplicar....
Introduzca el nombre del paquete en el campo Paquete. En el campo Nombre, introduzca ZCL_##_SOLUTION, donde ## representa su número de grupo.
Seleccione Siguiente.
Confirme la orden de transporte y seleccione Finalizar.
Active la copia.
Pulse Ctrl + F3 para activar la clase.
Tarea 2: Parámetro genérico
En la clase local LCL_CARRIER, ajuste las definiciones de los métodos FIND_PASSENGER_FLIGHT y FIND_CARGO_FLIGHT. En ambos métodos, escriba el parámetro de exportación e_flight como una variable de referencia basada en la clase local LCL_FLIGHT.
Pasos
En la clase local LCL_CARRIER, ajuste la definición del método FIND_CARGO_FLIGHT. Escriba el parámetro de retorno e_flight con LCL_FLIGHT en lugar de LCL_CARGO_FLIGHT. Asegúrese de guardar la modificación.
Ajuste el código de la siguiente manera:
123456789
METHODS find_cargo_flight
IMPORTING
i_airport_from_id TYPE /dmo/airport_from_id
i_airport_to_id TYPE /dmo/airport_to_id
i_from_date TYPE /dmo/flight_date
i_cargo TYPE /lrn/plane_actual_load
EXPORTING
e_flight TYPE REF TO lcl_flight
e_days_later TYPE i.
Analice la utilización del vuelo variable local en la implementación del método FIND_CARGO_FLIGHT.
Para visualizar el tipo de vuelo de la variable de referencia, sitúe el cursor en el nombre de la variable y pulse F2.
Analice la llamada del método FIND_CARGO_FLIGHT en el método IF_OO_ADT_CLASSRUN~MAIN en su clase global.
Para visualizar el tipo de la variable de referencia cargo_flight, sitúe el cursor en el nombre de la variable y pulse F2.
Ajuste la definición del método FIND_PASSENGER_FLIGHT de la misma manera. Escriba el parámetro de retorno e_flight con LCL_FLIGHT en lugar de LCL_PASSENGER_FLIGHT.
Ajuste el código de la siguiente manera:
123456789
METHODS find_passenger_flight
IMPORTING
i_airport_from_id TYPE /dmo/airport_from_id
i_airport_to_id TYPE /dmo/airport_to_id
i_from_date TYPE /dmo/flight_date
i_seats TYPE i
EXPORTING
e_flight TYPE REF TO lcl_flight
e_days_later TYPE i.
Active el código para verificar que esta modificación tampoco provoca errores de sintaxis.
Pulse Ctrl + F3 para activar el código.
Tarea 3: Atributo genérico
En la clase local LCL_CARRIER, defina vuelos de atributo de instancia privados en los que pueda almacenar referencias a instancias de LCL_PASSENGER_FLIGHT y LCL_CARGO_FLIGHT al mismo tiempo. Rellene el atributo en la implementación del método CONSTRUCTOR con el contenido combinado de los atributos passer_flights y cargo_flights.
Pasos
En la clase local LCL_FLIGHT, utilice una corrección rápida para generar un tipo de tabla pública que se base en esta clase (nombre sugerido para el tipo de tabla: tab).
Vaya a la definición de la clase local LCL_FLIGHT.
En la sentencia CLASS, sitúe el cursor en lcl_flight y pulse Ctrl + 1 para invocar las correcciones rápidas disponibles.
En la lista de correcciones rápidas disponibles, seleccione Generar tipo de tabla para lcl_flight.
La nueva sentencia TYPES debería tener este aspecto:
1
TYPES tab TYPE STANDARD TABLE OF REF TO lcl_flight WITH DEFAULT KEY.
En la sección privada de la clase local LCL_CARRIER, defina un nuevo atributo de instancia Vuelos. Escríbalo con el tipo de tabla que acaba de crear en la clase local LCL_FLIGHT.
Ajuste el código de la siguiente manera:
1234
DATA passenger_flights TYPE lcl_passenger_flight=>tt_flights.
DATA cargo_flights TYPE lcl_cargo_flight=>tt_flights.
DATA flights TYPE lcl_flight=>tab.
Ajuste la implementación del método CONSTRUCTOR de la clase local LCL_CARRIER. Después de llamar el método GET_FLIGHTS_BY_CARRIER de LCL_PASSENGER_FLIGHT, añada a los vuelos todas las referencias de objeto almacenadas en passer_flights.
Vaya a la implementación del método CONSTRUCTOR en la clase local LCL_CARRIER.
Antes de la sentencia ENDMETHOD, añada el siguiente código:
123
LOOP AT passenger_flights INTO DATA(passflight).
APPEND passflight TO flights.
ENDLOOP.
Si prefiere una comprensión de tabla, añada el siguiente código en su lugar:
12345
flights = VALUE #( BASE flights
FOR pflight IN passenger_flights (
pflight
)
).
De manera similar, implemente un bucle sobre cargo_flights y añada estas referencias a los vuelos también.
Antes de la sentencia ENDMETHOD, añada el siguiente código:
123
LOOP AT cargo_flights INTO DATA(cargoflight).
APPEND cargoflight TO flights.
ENDLOOP.
Si prefiere una comprensión de tabla, añada el siguiente código en su lugar:
12345
flights = VALUE #( BASE flights
FOR cflight IN cargo_flights (
cflight
)
).
Tarea 4: Acceso genérico y downcast
Elimine los atributos de instancia passer_flights y cargo_flights en la clase local LCL_CARRIER y sustitúyalos por los nuevos vuelos de atributo. Si el código accede a componentes específicos de las subclases, implemente un downcast.
Pasos
En la parte de definición de la clase local LCL_CARRIER, elimine o comente la definición de los atributos passer_flights y cargo_flights.
Seleccione las dos sentencias DATA y pulse Ctrl + < para añadir un signo de comentario delante de cada fila de código:
En el método CONSTRUCTOR, utilice declaraciones en línea para declarar airer_flights y cargo_flights como variables locales.
Ajuste el código de la siguiente manera:
1234567
DATA(passenger_flights) =
lcl_passenger_flight=>get_flights_by_carrier(
i_carrier_id = i_carrier_id ).
DATA(cargo_flights) =
lcl_cargo_flight=>get_flights_by_carrier(
i_carrier_id = i_carrier_id ).
Después de que el método llame con las declaraciones en línea, rellene un atributo de instancia privado con el número de filas en la variable local passer_flights (nombre sugerido: pf_count).
Consejo
Implemente primero la valoración. A continuación, utilice una corrección rápida para crear la declaración de atributo.
Ajuste el código de la siguiente manera:
12345
DATA(passenger_flights) =
lcl_passenger_flight=>get_flights_by_carrier(
i_carrier_id = i_carrier_id ).
pf_count = lines( passenger_flights ).
Sitúe el cursor en pf_count, pulse Ctrl + 1 y seleccione Declarar atributo pf_count.
De forma similar, rellene un atributo de instancia privado con el número de filas en la variable local cargo_flights (nombre sugerido: cf_count).
Ajuste el código de la siguiente manera:
12345
DATA(cargo_flights) =
lcl_cargo_flight=>get_flights_by_carrier(
i_carrier_id = i_carrier_id ).
cf_count = lines( cargo_flights ).
Sitúe el cursor en cf_count, pulse Ctrl + 1 y seleccione Declarar atributo cf_count.
En el método GET_OUTPUT, sustituya las funciones LINES integradas por los atributos que acaba de definir.
Ajuste el código de la siguiente manera:
123456
METHOD get_output.
APPEND |{ 'Carrier Name:'(001) } { me->name }| TO r_result.
APPEND |{ 'Passenger Flights:'(002) } { pf_count }| TO r_result.
APPEND |{ 'Average free seats:'(003) } { get_average_free_seats( ) }| TO r_result.
APPEND |{ 'Cargo Flights:'(004) } { cf_count }| TO r_result.
ENDMETHOD.
En el método FIND_CARGO_FLIGHT, sustituya el atributo cargo_flights por vuelos de atributo.
Ajuste el código de la siguiente manera:
12
LOOP AT me->flights INTO DATA(flight)
En la llamada del método GET_FREE_CAPACITY añada una expresión CAST.
Ajuste el código de la siguiente manera:
1234
IF connection_details-airport_from_id = i_airport_from_id
AND connection_details-airport_to_id = i_airport_to_id
AND CAST lcl_cargo_flight( flight )->get_free_capacity( ) >= i_cargo.
Para asegurarse de que solo considera instancias de LCL_CARGO_FLIGHT, amplíe la condición WHERE del LOOP.
Consejo
Recuerde que en las tablas internas con tipo de fila elemental se dirige al contenido con pseudo-componente table_line.
Ajuste el código de la siguiente manera:
123
LOOP AT me->flights INTO DATA(flight)
WHERE table_line->flight_date >= i_from_date
AND table_line IS INSTANCE OF lcl_cargo_flight.
Ajuste la implementación del método FIND_PASSENGER_FLIGHT de la misma manera.
Ajuste el código de la siguiente manera:
12345678910111213141516171819
LOOP AT me->flights INTO DATA(flight)
WHERE table_line->flight_date >= i_from_date
AND table_line IS INSTANCE OF lcl_passenger_flight.
DATA(connection_details) = flight->get_connection_details( ).
IF connection_details-airport_from_id = i_airport_from_id
AND connection_details-airport_to_id = i_airport_to_id
AND CAST lcl_passenger_flight( flight )->get_free_seats( ) >= i_seats.
DATA(days_later) = flight->flight_date - i_from_date.
IF days_later < e_days_later. e_flight = flight.
e_days_later = days_later.
ENDIF.
ENDIF.
ENDLOOP.
Ajuste la implementación del método GET_AVERAGE_FREE_SEATS. Utilice los vuelos de tabla internos en la reducción de tabla y añada una expresión CAST y una condición WHERE a la reducción. El número necesario de vuelos de pasajeros se almacena en el atributo pf_count creado anteriormente.
Ajuste el código de la siguiente manera:
12345678910111213141516
METHOD get_average_free_seats.
r_result = REDUCE #(
INIT i = 0
FOR flight IN flights
WHERE ( table_line IS INSTANCE OF lcl_passenger_flight )
NEXT i += CAST lcl_passenger_flight( flight )->get_free_seats( )
) / pf_count.
ENDMETHOD.
Active y pruebe su clase global como aplicación de consola.
Pulse Ctrl + F3.
Pulse F9.