Application Development and Automation 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: 
Read only

downcasting

Former Member
0 Likes
2,688

Hi Experts,

http://scn.sap.com/thread/3310329

I read the above posting to understand especially downcasting (widening casting ?=).

How I need to understand it generally?

subclass ?= superclass.

With widening casting (Downcasting)  =    accesing/calling  the methods of subclass to runtime.

Which method is called? Method of subclass or superclass?

If so, with the refrence "subclass" it is anyway possible to access to its methods. Why this casting??

With upcasting (Narrow Casting ) =   accesing/calling  the methods of superclass

superclass = subclass.

With the refrence "superclass" I am calling the methods of superclass.

Is that right?


Which method is called? Method of superclass or subclass  ?


Please correct me if I have misunderstood, it is very important to clarify me on this topic. I would be very grateful to everybody.

Regards

Alex

1 ACCEPTED SOLUTION
Read only

adam_krawczyk1
Contributor
0 Likes
1,868

Hi Alexander,

These are general object oriented inheritance rules, that are also valid for ABAP.

To simplify: always method of runtime object (actual existing object) is executed, independent of what is the reference type in declaration.

It means that parent method will be called only in case of having pure parent in runtime:

DATA lo_super TYPE REF TO lcl_super.

CRATE OBJECT lo_super.

lo_super->method( ).

If lcl_subclass has redefined method( ), then examples below will call subclass implementation:

DATA lo_subclass_from_super TYPE REF TO lcl_super.

CREATE OBJECT lo_subclass_from_super TYPE lcl_subclass.

lo_subclass_from_super->method( ).      " redefined implementation of lcl_subclass run     

DATA lo_subclass_temp TYPE REF TO lcl_subclass.

DATA lo_subclass_from_casting TYPE REF TO lcl_subclass.

DATA lo_super TYPE REF TO lcl_super.

CREATE OBJECT lo_subclass_temp.

lo_super = lo_subclass_temp.

lo_super->method( ).     " redefined implementation of lcl_subclass run

lo_subclass_from_casting ?= lo_super.    

lo_subclass_from_casting->method( ).      " redefined implementation of lcl_subclass run

And this example will throw exception:

DATA lo_subclass TYPE REF TO lcl_subclass.

DATA lo_super TYPE lcl_super.

CREATE lo_super.

" Exception thrown because how would method lo_subclass->subclass_method_only( ) run?

lo_subclass ?= lo_super.

The type declaration is only used to limit methods that we can use at compilation level - if LCL_SUPER type is used, only methods that are in LO_SUPER (optionally redefined in subclasses) can be called in code. If you have subclass type defined, you can use all methods - redefined from LCL_SUPER and new from LCL_SUBCLASS.

In general we use downcasting / widecasting if we have we parameter of type is LCL_SUPER but we know that LCL_SUBCLASS object is passed at runtime and we want to use additional method specific only to subclass. If we only operate on super class methods, there is no need of downcasting, just keep it mind that always methods of runtime object are run. Example:

  • We have method that requires parameter io_vehicle TYPE REF TO lcl_vehicle and executes lo_vehicle->move( ) inside it.
  • Lets call it lo_transport->transport_person( IMPORTING io_vehicle TYPE REF TO lcl_vehicle ).
  • If we pass object lo_car TYPE REF TO lcl_car that is subclass of lcl_vehicle, then actually lo_car->move( ) will be called even if parameter of method was lo_vehicle
  • If we pass another object lo_motor TYPE REF TO lcl_motor that is subclass of lcl_vehicle, then method lo_motor->move( ) will be called etc.
  • In this way you can program requirement that we have vehicle that can move (super class has move method) but how it will move depends on exact subclass object implementation.
  • Downcasting would be used  in case if we want to execute additional step only for motor in the lo_transport->transport_person( ), that is only in LCL_MOTOR class like put_helmet( ). You cannot use lo_vehicle->put_helment( ) because it does not exists in vehicle. You need to do:

DATA lo_motor TYPE REF TO lcl_motor.

lcl_motor ?= lo_vehicle.

lcl_motor->put_helmet( ).

  • Of course this code should be run only if we know that lcl_motor runtime object can be passed. We can add IF statement or try casting with TRY CATCH statement.

We do not need to use upcasting at all, we can always pass lo_subclass wherever lo_super is expected. I never use it.

Hope it helps.

Regards

Adam

5 REPLIES 5
Read only

GrahamRobbo
SAP Mentor
SAP Mentor
1,868

Hi Alex,

IMO - all these questions just lead to more questions that are similar.

I think the best thing for you to do is just to try it and see. Create a class with some public & protected methods that simply call write statements to show you when they execute. Then create one or more subclasses and redefine some of those methods to have their own write statements. Then have a play and see what works and what doesn't.

Cheers

Graham Robbo

Read only

Former Member
0 Likes
1,868

To your hint:

How do you know that I have not already done that?

To my posting again:

Which sense does it make to downcast an object in order to call always a method

of subclass. I will never understand that

Read only

0 Likes
1,868

Hi Alexander,

in addition to what Adam wrote below and hoping that I understood your question correctly: you need to distinguish between designtime and runtime when looking at "method of subclass or superclass is called".

You will at runtime always execute the method that belongs to the instance you created, so the creating of the instance defines whether it is the super- or subclass.

A widening cast just helps you at design time: if for whatever reason you happen to have access to a superclass (interface restrictions for example), but you know that the caller might provide you with a subclass, you can use the widening cast to gain access to the functionality of the subclass at designtime.

Am I making sense?

Best regards,

Thorsten

Read only

adam_krawczyk1
Contributor
0 Likes
1,869

Hi Alexander,

These are general object oriented inheritance rules, that are also valid for ABAP.

To simplify: always method of runtime object (actual existing object) is executed, independent of what is the reference type in declaration.

It means that parent method will be called only in case of having pure parent in runtime:

DATA lo_super TYPE REF TO lcl_super.

CRATE OBJECT lo_super.

lo_super->method( ).

If lcl_subclass has redefined method( ), then examples below will call subclass implementation:

DATA lo_subclass_from_super TYPE REF TO lcl_super.

CREATE OBJECT lo_subclass_from_super TYPE lcl_subclass.

lo_subclass_from_super->method( ).      " redefined implementation of lcl_subclass run     

DATA lo_subclass_temp TYPE REF TO lcl_subclass.

DATA lo_subclass_from_casting TYPE REF TO lcl_subclass.

DATA lo_super TYPE REF TO lcl_super.

CREATE OBJECT lo_subclass_temp.

lo_super = lo_subclass_temp.

lo_super->method( ).     " redefined implementation of lcl_subclass run

lo_subclass_from_casting ?= lo_super.    

lo_subclass_from_casting->method( ).      " redefined implementation of lcl_subclass run

And this example will throw exception:

DATA lo_subclass TYPE REF TO lcl_subclass.

DATA lo_super TYPE lcl_super.

CREATE lo_super.

" Exception thrown because how would method lo_subclass->subclass_method_only( ) run?

lo_subclass ?= lo_super.

The type declaration is only used to limit methods that we can use at compilation level - if LCL_SUPER type is used, only methods that are in LO_SUPER (optionally redefined in subclasses) can be called in code. If you have subclass type defined, you can use all methods - redefined from LCL_SUPER and new from LCL_SUBCLASS.

In general we use downcasting / widecasting if we have we parameter of type is LCL_SUPER but we know that LCL_SUBCLASS object is passed at runtime and we want to use additional method specific only to subclass. If we only operate on super class methods, there is no need of downcasting, just keep it mind that always methods of runtime object are run. Example:

  • We have method that requires parameter io_vehicle TYPE REF TO lcl_vehicle and executes lo_vehicle->move( ) inside it.
  • Lets call it lo_transport->transport_person( IMPORTING io_vehicle TYPE REF TO lcl_vehicle ).
  • If we pass object lo_car TYPE REF TO lcl_car that is subclass of lcl_vehicle, then actually lo_car->move( ) will be called even if parameter of method was lo_vehicle
  • If we pass another object lo_motor TYPE REF TO lcl_motor that is subclass of lcl_vehicle, then method lo_motor->move( ) will be called etc.
  • In this way you can program requirement that we have vehicle that can move (super class has move method) but how it will move depends on exact subclass object implementation.
  • Downcasting would be used  in case if we want to execute additional step only for motor in the lo_transport->transport_person( ), that is only in LCL_MOTOR class like put_helmet( ). You cannot use lo_vehicle->put_helment( ) because it does not exists in vehicle. You need to do:

DATA lo_motor TYPE REF TO lcl_motor.

lcl_motor ?= lo_vehicle.

lcl_motor->put_helmet( ).

  • Of course this code should be run only if we know that lcl_motor runtime object can be passed. We can add IF statement or try casting with TRY CATCH statement.

We do not need to use upcasting at all, we can always pass lo_subclass wherever lo_super is expected. I never use it.

Hope it helps.

Regards

Adam

Read only

0 Likes
1,868

Hi Adam,

pls. can u check  if this coding is correct.

CLASS lcl_vehicle DEFINITION.

PUBLIC SECTION.

METHODS: move,

transport_person IMPORTING io_vehicle TYPE REF TO lcl_vehicle.

ENDCLASS.

CLASS lcl_car DEFINITION INHERITING FROM lcl_vehicle.

PUBLIC SECTION.

METHODS: move Redefinition,

transport_person Redefinition .

ENDCLASS.

CLASS lcl_motor DEFINITION INHERITING FROM lcl_vehicle.

PUBLIC SECTION.

METHODS: move Redefinition,

transport_person Redefinition .

ENDCLASS.

CLASS lcl_vehicle IMPLEMENTATION.

METHOD move.

WRITE: / 'Methode der vehicle'.

ENDMETHOD.

METHOD transport_person.

WRITE: / 'transport_person der Vehicleklasse'.

ENDMETHOD.

ENDCLASS.

CLASS lcl_car IMPLEMENTATION.

METHOD move.

WRITE: / 'Method of car'.

ENDMETHOD.

METHOD transport_person.

WRITE: / 'transport_person der Carklasse'.

ENDMETHOD.

ENDCLASS.

CLASS lcl_motor IMPLEMENTATION.

METHOD move.

WRITE: / 'Method of motor'.

ENDMETHOD.

METHOD transport_person.

WRITE: / 'transport_person der Motorklasse'.

ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

DATA lo_vehicle TYPE REF TO lcl_vehicle.

DATA lo_car TYPE REF TO lcl_car.

DATA lo_motor TYPE REF TO lcl_motor.

CREATE OBJECT lo_vehicle.

CREATE OBJECT lo_car.

CALL METHOD lo_car->transport_person

EXPORTING

io_vehicle = lo_vehicle.

Regards

Alex