‎2013 Mar 03 3:52 PM
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
‎2013 Mar 04 8:40 AM
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:
DATA lo_motor TYPE REF TO lcl_motor.
lcl_motor ?= lo_vehicle.
lcl_motor->put_helmet( ).
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
‎2013 Mar 03 11:58 PM
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
‎2013 Mar 04 8:31 AM
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
‎2013 Mar 04 8:47 AM
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
‎2013 Mar 04 8:40 AM
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:
DATA lo_motor TYPE REF TO lcl_motor.
lcl_motor ?= lo_vehicle.
lcl_motor->put_helmet( ).
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
‎2013 Mar 04 10:12 AM
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