No exercício anterior, você criou uma classe superior comum LCL_FLIGHT para as classes LCL_PASSENGER_FLIGHT e LCL_CARGO_FLIGHT. Agora, você modificará a classe local LCL_CARRIER para utilizar a relação de herança. Você digitará variáveis de referência usadas como parâmetros para o tipo da classe superior e, em vez de dois atributos de instância separados passenger_flights e cargo_flights, definirá voos de atributo de instância única nos quais você pode armazenar referências a todas as instâncias de voo, independentemente de serem voos de passageiro ou de carga.
Tarefa 1: Copiar modelo (opcional)
Copie a classe modelo /LRN/CL_S4D401_OOS_INHERITANCE. Se você tiver concluído o exercício anterior, pode ignorar esta tarefa e continuar processando sua classe ZCL_##_SOLUTION.
Etapas
Copie a classe /LRN/CL_S4D401_OOS_INHERITANCE para uma classe em seu próprio pacote (nome sugerido: ZCL_##_SOLUTION, onde ## representa seu número de grupo).
No Explorador de projetos, clique com o botão direito na classe /LRN/CL_S4D401_OOS_INHERITANCE para abrir o menu de contexto.
No menu de contexto, selecione Duplicar....
Insira o nome do seu pacote no campo Pacote. No campo Nome, insira ZCL_##_SOLUTION, em que ## representa seu número de grupo.
Selecione Avançar.
Confirme a ordem de transporte e selecione Concluir.
Ative a cópia.
Pressione Ctrl + F3 para ativar a classe.
Tarefa 2: Parâmetro genérico
Na classe local LCL_CARRIER, ajuste as definições dos métodos FIND_PASSENGER_FLIGHT e FIND_CARGO_FLIGHT. Nos dois métodos, digite o parâmetro de exportação e_flight como uma variável de referência com base na classe local LCL_FLIGHT.
Etapas
Na classe local LCL_CARRIER, ajuste a definição do método FIND_CARGO_FLIGHT. Digite o parâmetro de retorno e_flight com LCL_FLIGHT em vez de LCL_CARGO_FLIGHT. Certifique-se de gravar a modificação.
Ajuste o código da seguinte forma:
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.
Analise a utilização do voo de variável local na implementação do método FIND_CARGO_FLIGHT.
Para exibir o tipo de voo da variável de referência, posicione o cursor no nome da variável e pressione F2.
Analise a chamada do método FIND_CARGO_FLIGHT no método IF_OO_ADT_CLASSRUN~MAIN na sua classe global.
Para exibir o tipo da variável de referência cargo_flight, posicione o cursor no nome da variável e pressione F2.
Ajuste a definição do método FIND_PASSENGER_FLIGHT da mesma forma. Digite o parâmetro de retorno e_flight com LCL_FLIGHT em vez de LCL_PASSENGER_FLIGHT.
Ajuste o código da seguinte forma:
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.
Ative o código para verificar se essa modificação também não causa erros de sintaxe.
Pressione Ctrl + F3 para ativar o código.
Tarefa 3: Atributo genérico
Na classe local LCL_CARRIER, defina voos de atributo de instância privados nos quais você pode armazenar referências a instâncias de LCL_PASSENGER_FLIGHT e LCL_CARGO_FLIGHT ao mesmo tempo. Preencha o atributo na implementação do método CONSTRUCTOR com o conteúdo combinado dos atributos passenger_flights e cargo_flights.
Etapas
Na classe local LCL_FLIGHT, utilize uma correção rápida para gerar um tipo de tabela pública baseado nessa classe (nome sugerido para o tipo de tabela: tab).
Vá para a definição da classe local LCL_FLIGHT.
Na instrução CLASS, posicione o cursor em lcl_flight e pressione Ctrl + 1 para chamar as correções rápidas disponíveis.
Na lista de soluções rápidas disponíveis, selecione Gerar tipo de tabela para lcl_flight.
A nova instrução TYPES deve ter o seguinte aspecto:
1
TYPES tab TYPE STANDARD TABLE OF REF TO lcl_flight WITH DEFAULT KEY.
Na seção privada da classe local LCL_CARRIER, defina novos voos de atributo de instância. Digite o mesmo com o tipo de tabela que você acabou de criar na classe local LCL_FLIGHT.
Ajuste o código da seguinte forma:
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 a implementação do método CONSTRUCTOR da classe local LCL_CARRIER. Depois de você ter chamado o método GET_FLIGHTS_BY_CARRIER de LCL_PASSENGER_FLIGHT, adicione todas as referências a objetos armazenadas em passenger_flights para voos.
Vá para a implementação do método CONSTRUCTOR na classe local LCL_CARRIER.
Antes da instrução ENDMETHOD, adicione o seguinte código:
123
LOOP AT passenger_flights INTO DATA(passflight).
APPEND passflight TO flights.
ENDLOOP.
Se você preferir uma compreensão de tabela, adicione o seguinte código:
12345
flights = VALUE #( BASE flights
FOR pflight IN passenger_flights (
pflight
)
).
Da mesma forma, implemente um loop sobre cargo_flights e adicione essas referências a voos também.
Antes da instrução ENDMETHOD, adicione o seguinte código:
123
LOOP AT cargo_flights INTO DATA(cargoflight).
APPEND cargoflight TO flights.
ENDLOOP.
Se você preferir uma compreensão de tabela, adicione o seguinte código:
12345
flights = VALUE #( BASE flights
FOR cflight IN cargo_flights (
cflight
)
).
Tarefa 4: Acesso genérico e down-cast
Elimine os atributos de instância passenger_flights e cargo_flights na classe local LCL_CARRIER e substitua-os pelos novos voos de atributo. Quando o código acessa componentes específicos das subclasses, implemente um down-cast.
Etapas
Na parte de definição da classe local LCL_CARRIER, remova ou comente a definição dos atributos passenger_flights e cargo_flights.
Selecione as duas instruções DATA e pressione Ctrl + < para adicionar um sinal de comentário na frente de cada linha de código:
No método CONSTRUCTOR, utilize declarações inline para declarar passenger_flights e cargo_flights como variáveis locais.
Ajuste o código da seguinte forma:
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 ).
Após a chamada do método com as declarações inline, preencha um atributo de instância privado com o número de linhas na variável local passenger_flights (nome sugerido: pf_count).
Dica
Implementar primeiro a avaliação. Em seguida, utilize uma correção rápida para criar a declaração de atributo.
Ajuste o código da seguinte forma:
12345
DATA(passenger_flights) =
lcl_passenger_flight=>get_flights_by_carrier(
i_carrier_id = i_carrier_id ).
pf_count = lines( passenger_flights ).
Posicione o cursor em pf_count, pressione Ctrl + 1 e selecione Declare attribute pf_count.
Da mesma forma, preencha um atributo de instância privado com o número de linhas na variável local cargo_flights (nome sugerido: cf_count).
Ajuste o código da seguinte forma:
12345
DATA(cargo_flights) =
lcl_cargo_flight=>get_flights_by_carrier(
i_carrier_id = i_carrier_id ).
cf_count = lines( cargo_flights ).
Posicione o cursor em cf_count, pressione Ctrl + 1 e selecione Declare attribute cf_count.
No método GET_OUTPUT, substitua as funções LINES integradas pelos atributos que você acabou de definir.
Ajuste o código da seguinte forma:
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.
No método FIND_CARGO_FLIGHT, substitua o atributo cargo_flights pelo atributo flights.
Ajuste o código da seguinte forma:
12
LOOP AT me->flights INTO DATA(flight)
Na chamada do método GET_FREE_CAPACITY, adicione uma expressão CAST.
Ajuste o código da seguinte forma:
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 garantir que você só considera instâncias de LCL_CARGO_FLIGHT, amplie a condição WHERE de LOOP.
Dica
Lembre-se de que, em tabelas internas com o tipo de linha elementar, você aborda o conteúdo com pseudo-componente table_line.
Ajuste o código da seguinte forma:
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 a implementação do método FIND_PASSENGER_FLIGHT da mesma forma.
Ajuste o código da seguinte forma:
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 a implementação do método GET_AVERAGE_FREE_SEATS. Use os voos de tabela interna na redução de tabela e adicione uma expressão CAST e uma condição WHERE à redução. O número necessário de voos de passageiros é armazenado no atributo pf_count criado acima.
Ajuste o código da seguinte forma:
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.
Ative e teste sua classe global como aplicativo de console.
Pressione Ctrl + F3.
Pressione F9.