Polymorphism
Polymorphism: When the same method is implemented differently in different classes. This can be done using enheritance, by redefining a method from the superclass in subclasses and implement it differently.
Classes:
lcl_airplane Superclass
lcl_cargo_airplane Subclass
lcl_passenger_airplane Subclass
The method estimate_fuel_consumption is implemented differently in the 3 classes, as it depends on the airplane type.
Object from different classes are stored in an internal table (plane_list) consisting of references to the superclass, and the processed
identically for all the classes.
What coding for the estimate_fuel_consumption method taht is actually executed, depends on the dynamic type of the plane reference variable,
that is, depends on which object plane points to.
DATA: cargo_plane TYPE REF to lcl_cargo_airplane,
passenger_plane TYPE REF to lcl_passenger_airplane,
plane_list TYPE TABLE OF REF TO lcl_airplane.
* Creating the list of references
CREATE OBJECT cargo_plane.
APPEND cargo_plane to plane_list.
CREATE OBJECT passenger_plane
APPEND passenger_plane to plane list.
* Generic method for calucalting required fuel
METHOD calculate required_fuel.
DATA: plane TYPE REF TO lcl_airplane.
LOOP AT plane_list INTO plane.
re_fuel = re_fuel + plane->estimate_fuel_consumption( distance ).
ENDLOOP.
ENDMETHOD.
Working example:
This example assumes that the classes lcl_airplane, lcl_passnger_airplane and lcl_cargo plane (Se Subcallsing) exists.
Create objects of type lcl_cargo_plane and lcl_passenger_airplane, adds them to a list in lcl_carrier, and displays the list.
*&———————————————————————*
*& Include ZBC404_HF_LCL_CARRIER *
*& *
*&———————————————————————*
* CLASS lcl_carrier DEFINITION *
*———————————————————————-*
CLASS lcl_carrier DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF flight_list_type,
connid TYPE sflight-connid,
fldate TYPE sflight-fldate,
airplane TYPE REF TO lcl_airplane,
seatsocc TYPE sflight-seatsocc,
cargo(5) TYPE p DECIMALS 3,
END OF flight_list_type.
METHODS: constructor IMPORTING im_name TYPE string,
get_name RETURNING value(ex_name) TYPE string,
add_a_new_airplane IMPORTING
im_airplane TYPE REF TO lcl_airplane,
create_a_new_flight importing
im_connid type sflight-connid
im_fldate type sflight-fldate
im_airplane type ref to lcl_airplane
im_seatsocc type sflight-seatsocc
optional
im_cargo type p optional,
display_airplanes.
PRIVATE SECTION.
DATA: name TYPE string,
list_of_airplanes TYPE TABLE OF REF TO lcl_airplane,
list_of_flights TYPE TABLE OF flight_list_type.
ENDCLASS.
*———————————————————————*
* CLASS lcl_carrier IMPLEMENTATION
*———————————————————————*
CLASS lcl_carrier IMPLEMENTATION.
METHOD constructor.
name = im_name.
ENDMETHOD.
METHOD get_name.
ex_name = name.
ENDMETHOD.
METHOD create_a_new_flight.
DATA: wa_list_of_flights TYPE flight_list_type.
wa_list_of_flights-connid = im_connid.
wa_list_of_flights-fldate = im_fldate.
wa_list_of_flights-airplane = im_airplane.
IF im_seatsocc IS INITIAL.
wa_list_of_flights-cargo = im_cargo.
ELSE.
wa_list_of_flights-seatsocc = im_seatsocc.
ENDIF.
APPEND wa_list_of_flights TO list_of_flights.
ENDMETHOD.
METHOD add_a_new_airplane.
APPEND im_airplane TO list_of_airplanes.
ENDMETHOD.
METHOD display_airplanes.
DATA: l_airplane TYPE REF TO lcl_airplane.
LOOP AT list_of_airplanes INTO l_airplane.
CALL METHOD l_airplane->display_attributes.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
REPORT zbc404_hf_main .
*******************************************************************
* This reprort uses class LCL_AIRPLNAE and subclasses
* LCL_CARGO_PLANE and LCL_PASSENGER_AIRPLANE and class LCL_CARRIER
*******************************************************************
* Super class for airplanes
INCLUDE zbc404_hf_lcl_airplane.
* Sub classes for airplanes
INCLUDE zbc404_hf_lcl_passenger_plane.
INCLUDE zbc404_hf_lcl_cargo_plane.
* Carrier class
INCLUDE zbc404_hf_lcl_carrier.
DATA:
* Type ref to classes
o_passenger_airplane TYPE REF TO lcl_passenger_airplane,
o_passenger_airplane2 TYPE REF TO lcl_passenger_airplane,
o_cargo_plane TYPE REF TO lcl_cargo_plane,
o_cargo_plane2 TYPE REF TO lcl_cargo_plane,
o_carrier TYPE REF TO lcl_carrier.
START-OF-SELECTION.
* Create objects
CREATE OBJECT o_passenger_airplane
EXPORTING
im_name = ‘LH505’
im_planetype = ‘Boing 747’
im_n_o_seats = 350.
CREATE OBJECT o_passenger_airplane2
EXPORTING
im_name = ‘SK333’
im_planetype = ‘MD80’
im_n_o_seats = 110.
CREATE OBJECT o_cargo_plane
EXPORTING
im_name = ‘AR13’
im_planetype = ‘DC 3’
im_cargomax = 35.
CREATE OBJECT o_cargo_plane2
EXPORTING
im_name = ‘AFL124’
im_planetype = ‘Iljutsin 2’
im_cargomax = 35000.
CREATE OBJECT o_carrier
EXPORTING im_name = ‘Spritisch Airways’.
* Add passenger and cargo planes to the list of airplanes
CALL METHOD o_carrier->add_a_new_airplane
EXPORTING im_airplane = o_passenger_airplane.
CALL METHOD o_carrier->add_a_new_airplane
EXPORTING im_airplane = o_passenger_airplane2.
CALL METHOD o_carrier->add_a_new_airplane
EXPORTING im_airplane = o_cargo_plane.
CALL METHOD o_carrier->add_a_new_airplane
EXPORTING im_airplane = o_cargo_plane2.
* Display list of airplanes
call method o_carrier->display_airplanes.
Result:
Name: LH505 Planetype: Boing 747
No. seats: 350
Name: SK333 Planetype: MD80
No. seats: 110
Name: AR13 Planetype: DC 3
Cargo max: 35,0000
Name: AFL124 Planetype: Iljutsin 2
Cargo max: 35.000,0000
Events
Below is a simple example of how to implement an event.
REPORT zbc404_hf_events_5.
*———————————————————————*
* CLASS lcl_dog DEFINITION
*———————————————————————*
CLASS lcl_dog DEFINITION.
PUBLIC SECTION.
* Declare events
EVENTS:
dog_is_hungry
EXPORTING value(ex_time_since_last_meal) TYPE i.
METHODS:
constructor
IMPORTING im_name TYPE string,
set_time_since_last_meal
IMPORTING im_time TYPE i,
on_dog_is_hungry FOR EVENT dog_is_hungry OF lcl_dog
IMPORTING ex_time_since_last_meal.
ENDCLASS.
*———————————————————————*
* CLASS lcl_dog IMPLEMENTATION
*———————————————————————*
CLASS lcl_dog IMPLEMENTATION.
METHOD constructor.
WRITE: / ‘I am a dog and my name is’, im_name.
ENDMETHOD.
METHOD set_time_since_last_meal.
IF im_time < 4.
SKIP 1.
WRITE: / ‘You fool, I am not hungry yet’.
ELSE.
* Subsrcribe for event:
* set handler <Event handler method>
* FOR <ref_sender>!FOR ALL INSTANCES [ACTIVATION <var>]
SET HANDLER on_dog_is_hungry FOR ALL INSTANCES ACTIVATION ‘X’.
* Raise event
RAISE EVENT dog_is_hungry
EXPORTING ex_time_since_last_meal = im_time.
ENDIF.
ENDMETHOD.
METHOD on_dog_is_hungry.
* Event method, called when the event dog_is_hungry is raised
SKIP 1.
WRITE: / ‘You son of a bitch. I have not eaten for more than’,
ex_time_since_last_meal, ‘ hours’.
WRITE: / ‘Give me something to eat NOW!’.
ENDMETHOD.
ENDCLASS.
*———————————————————————*
* R E P O R T
*———————————————————————*
DATA: o_dog1 TYPE REF TO lcl_dog.
START-OF-SELECTION.
CREATE OBJECT o_dog1 EXPORTING im_name = ‘Beefeater’.
CALL METHOD o_dog1->set_time_since_last_meal
EXPORTING im_time = 2.
* This method call will raise the event dog_is_hungy
* because time > 3
CALL METHOD o_dog1->set_time_since_last_meal
EXPORTING im_time = 5.
Result:
I am a dog and my name is Beefeater
You fool, I am not hungry yet
You son of a bitch. I have not eaten for more than 5 hours
Give me something to eat NOW!