Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Narrow & Widening cast

Former Member
0 Kudos

Hello, I'm trying to understand narrow & widening cast, for this reason I develop a simple class in order to understand correctly. Here is my source code:

REPORT  ZBC_OBJECTS.

CLASS lcl_vehicle DEFINITION.
   PUBLIC SECTION.
   METHODS: constructor IMPORTING
                        im_max_speed TYPE i
                        im_number_of_wheels TYPE i.
   PRIVATE SECTION.

   DATA: max_speed TYPE i,
         number_of_wheels TYPE i.

ENDCLASS.

CLASS lcl_vehicle IMPLEMENTATION.

METHOD constructor.
   max_speed = im_max_speed.
   number_of_wheels = im_number_of_wheels.
ENDMETHOD.

ENDCLASS.

CLASS lcl_truck DEFINITION INHERITING FROM lcl_vehicle.
   PUBLIC SECTION.
   METHODS: constructor IMPORTING
     im_max_speed TYPE i
     im_number_of_wheels TYPE i
     im_load_capacity TYPE i.
   PRIVATE SECTION.
   DATA: load_capacity TYPE i.
   ENDCLASS.

   CLASS lcl_truck IMPLEMENTATION.
     METHOD constructor.
     super->constructor(
     im_max_speed = im_max_speed
     im_number_of_wheels = im_number_of_wheels ).
     load_capacity = im_load_capacity.
     ENDMETHOD.
     ENDCLASS.


DATA: vehicle TYPE REF TO lcl_vehicle,
       truck TYPE REF TO lcl_truck.

START-OF-SELECTION.

CREATE OBJECT vehicle EXPORTING
   im_max_speed = 325
   im_number_of_wheels = 4.

CREATE OBJECT truck EXPORTING
   im_max_speed = 100
   im_number_of_wheels = 8
   im_load_capacity = 5000.


vehicle ?= truck. " Vehicle now have attribute +load_capacity (Widening cast)

the widening cast is working (I think), how can I "simulate" the narrowing cast in my own example. Thanks!

1 ACCEPTED SOLUTION

adam_krawczyk1
Contributor
0 Kudos

Hi Georgi,

Please let me give some references to casting examples:

http://scn.sap.com/message/13989885#13989885 - simple example with pizza

http://scn.sap.com/message/13857599#13857599 - example with vehicles

In your case if you want to see example of narrow casting then just modify your code by adding new variable lo_truck_vehicle_type:

DATA: lo_vehicle TYPE REF TO lcl_vehicle,
       lo_truck TYPE REF TO lcl_truck,

       lo_truck_vehicle_type TYPE REF TO lcl_vehicle.



START-OF-SELECTION.

CREATE OBJECT lo_vehicle EXPORTING
   im_max_speed = 325
   im_number_of_wheels = 4.

CREATE OBJECT lo_truck EXPORTING
   im_max_speed = 100
   im_number_of_wheels = 8
   im_load_capacity = 5000.

lo_vehicle ?= lo_truck. " Vehicle now have attribute +load_capacity (Widening cast)

lo_truck_vehicle_type ?= lo_vehicle.     " you can simply assign same type level

" In line below we are assigning basic type to extended type because we are sure that runtime

" object type is actually TRUCK even if variable type is VEHICLE

lo_truck ?= lo_truck_vehicle_type.

    

Of  course code above is just for demonstration. In real life you may have method that has input parameter TYPE LCL_VEHICLE. Let say it is driver_over_bridge You cannot change method signature (maybe it is SAP standard and you want just to add implicit enhancement inside method). In case if you know that runtime instance of LCL_TRUCK is given, mail should be sent if truck is too heavy. But the weight/load_capacity is only attribute of truck, not the vehicle. So you can add implementation to the method:

TRY.

     DATA  lo_truck TYPE LCL_TRUCK.

     lo_truck ?= lo_vehicle.

     " no error - yes it is a truck instance

     IF ( lo_truck->get_load_capacity( ) > 1000 ).     " you have access to truck methods/atributes here if you need

          send_email( "vehicle is truck type, may be too heavy" ).

     ENDIF.

CATCH cx_root.

     " it was not truck, do not make any action

ENDTRY.

Hope this helps.

Regards

Adam

6 REPLIES 6

hendrik_brandes
Contributor
0 Kudos

Hello Goergi,

A widening cast should be if you create an instance like this:

create object vehicle type lcl_truck.

truck ?= vehicle.

Kind regards,

Hendrik

0 Kudos

Exactly!

But we've a "Houston, we have a problem" situation here The constructor of the sub-class LCL_VEHICLE has a mandatory param load_capacity which would cause the problem.

So the OP needs to change the definition of the constructor to (which i think he should do) -

METHODS: constructor IMPORTING

       im_max_speed TYPE i

       im_number_of_wheels TYPE i

       im_load_capacity TYPE i OPTIONAL. "-->Change this param to Optional

Otherwise he has to follow 's solution

Imho all the CONSTRUCTORs of an inheritance tree should have the same interface, what do you say?

BR,

Suhas

0 Kudos

In my opinion constructor parameters should reflect what is really needed for object initialization, so I would not restrict to the rule of common interface. But if classes in inheritance tree requires same parameters for initialization, then it is ok. We must be aware when using optional parameters - not for syntax simplification but to reflect requirements that load_capacity may be skipped for truck in our case and truck can exists without this value.

On the other hand I do not like restriction in ABAP that only one constructor is allowed. That is why I prefer to create objects by factory methods (create_vehicle) with different parameters set unless I am really sure that object always needs same mandatory parameters for initialization - then constructor is desired.

Kind regards

Adam

Former Member
0 Kudos

Hi Georgi,

Refer to this link on narrow casting. This link has same example:

http://saptechnical.com/Tutorials/OOPS/Casting/Index.htm

Former Member
0 Kudos

 

DATA: r_vehicle TYPE REF TO lcl_vehicle,

r_truck TYPE REF TO lcl_truck,

 

Here  lcl_truck is inherting LCL_vehicle.

* Narrowing Cast

 

r_vehicle = r_truck.

 

* Use of the subclass instance in the superclass context

 

ret = r_vehicle->MethodOFSuperclass( ).

 

The assignment of a subclass instance to a reference variable of the type "reference to superclass" is described as a narrowing cast, because you are switching from a more detailed view to a one with less detail.

You can now access the subclass method(which is inherited from superclass) with the help of superclass reference.

adam_krawczyk1
Contributor
0 Kudos

Hi Georgi,

Please let me give some references to casting examples:

http://scn.sap.com/message/13989885#13989885 - simple example with pizza

http://scn.sap.com/message/13857599#13857599 - example with vehicles

In your case if you want to see example of narrow casting then just modify your code by adding new variable lo_truck_vehicle_type:

DATA: lo_vehicle TYPE REF TO lcl_vehicle,
       lo_truck TYPE REF TO lcl_truck,

       lo_truck_vehicle_type TYPE REF TO lcl_vehicle.



START-OF-SELECTION.

CREATE OBJECT lo_vehicle EXPORTING
   im_max_speed = 325
   im_number_of_wheels = 4.

CREATE OBJECT lo_truck EXPORTING
   im_max_speed = 100
   im_number_of_wheels = 8
   im_load_capacity = 5000.

lo_vehicle ?= lo_truck. " Vehicle now have attribute +load_capacity (Widening cast)

lo_truck_vehicle_type ?= lo_vehicle.     " you can simply assign same type level

" In line below we are assigning basic type to extended type because we are sure that runtime

" object type is actually TRUCK even if variable type is VEHICLE

lo_truck ?= lo_truck_vehicle_type.

    

Of  course code above is just for demonstration. In real life you may have method that has input parameter TYPE LCL_VEHICLE. Let say it is driver_over_bridge You cannot change method signature (maybe it is SAP standard and you want just to add implicit enhancement inside method). In case if you know that runtime instance of LCL_TRUCK is given, mail should be sent if truck is too heavy. But the weight/load_capacity is only attribute of truck, not the vehicle. So you can add implementation to the method:

TRY.

     DATA  lo_truck TYPE LCL_TRUCK.

     lo_truck ?= lo_vehicle.

     " no error - yes it is a truck instance

     IF ( lo_truck->get_load_capacity( ) > 1000 ).     " you have access to truck methods/atributes here if you need

          send_email( "vehicle is truck type, may be too heavy" ).

     ENDIF.

CATCH cx_root.

     " it was not truck, do not make any action

ENDTRY.

Hope this helps.

Regards

Adam