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: 

widening casting

Former Member
0 Kudos

Hi,

I am a debutant in ABAP OO. I am trying to understand the concept of Widening casting with lots of example found in SDN, but still I can't come to any conclusion on this.

Well I understood from one of the example that , before doing the widening , we have to do narrow casting..



 DATA: lo_animal TYPE REF TO lcl_animal,   " Super Class
        lo_lion          TYPE REF TO lcl_lion,        " Sub class
        lo_tmp_lion   TYPE REF TO lcl_lion.       " Sub class

  CREATE OBJECT lo_tmp_lion.
  lo_animal = lo_tmp_lion.                  " Narrow Casting

lo_lion ?= lo_animal.     " Widening 

Here my question is why do we have to assign the instance of lo_animal to lo_lion which is having the same instance of lo_lion( lo_lion & lo_tmp_lion are reference var of same class ). and i also found an another example from one of the SDN thread for widening which i really can't undersatnd.



DATA lo_tabledescr TYPE REF TO cl_abap_tabledescr.
DATA lo_structdescr TYPE REF TO cl_abap_structdescr.
DATA lv_linetypename  TYPE string.

TRY.
    lo_tabledescr   ?= cl_abap_typedescr=>describe_by_name( 'BAPIRET2_T' ).
    lo_structdescr  ?= lo_tabledescr->get_table_line_type( ).
  CATCH cx_sy_move_cast_error.
    MESSAGE 'Error in downcast!' TYPE 'A'.
ENDTRY.
lv_linetypename = lo_structdescr->get_relative_name( ).
WRITE: /, lv_linetypename.

* Alternative way using dynamic calling

DATA lo_typedescr_tab TYPE REF TO cl_abap_typedescr.
DATA lo_typedescr_str TYPE REF TO cl_abap_typedescr.

lo_typedescr_tab   = cl_abap_typedescr=>describe_by_name( 'BAPIRET2_T' ).
TRY.
    CALL METHOD lo_typedescr_tab->('GET_TABLE_LINE_TYPE')
      RECEIVING
        p_descr_ref = lo_typedescr_str.
  CATCH cx_sy_dyn_call_error.
    MESSAGE 'Error in dynamic call!' TYPE 'A'.
ENDTRY.
lv_linetypename = lo_typedescr_str->get_relative_name( ).
WRITE: /, lv_linetypename, '...again'.

Please give me some hints to break through this.

Thanks in advace,

Eti.

1 ACCEPTED SOLUTION

naimesh_patel
Active Contributor
0 Kudos

Casting would be used whenever you want to use the Generic Type e.g. LCL_ANIMAL, CL_ABAP_TYPEDESCR are used to defined the parameter or variables. But they would contains more Specific Type e.g. Reference of LION, or reference of Structure object.

This code was to just set up the data which would be used for Widening cast later on. Assume that this piece of code is in the Perform or method, and LO_ANIMAL is the returning parameter. So, when you create the object LO_TMP_LION and assign it to LO_ANIMAL, at runtime it would still contain the object reference of the LCL_LION.

 
  CREATE OBJECT lo_tmp_lion.
  lo_animal = lo_tmp_lion.                  " Narrow Casting

Similar process happens when you use the method DESCRIBE_BY_NAME of the class CL_ABAP_TYPEDESCR. Returning Parameter P_DESCR_REF is declared with the CL_ABAP_TYPEDESCR. But based on the provided importing parameter P_NAME, the method will generate different type of object references. Since the given name in your example is table type, you are receiving that object reference in the variable defined with the type CL_ABAP_TABLEDESCR. Based on the type of the P_NAME system will generate the object so, it doesnu2019t need to do the narrow casting as what I did in my old and poor example at [ABAP Objects: Widening Cast|http://help-abap.zevolving.com/2008/09/abap-objects-widening-cast/].

@Suhas

Why not to mention golden rule with Golden color

The golden-rule for assignment of reference variables is,

Dynamic type of a ref. variable must always be more specific than the static type.

Regards,

Naimesh Patel

5 REPLIES 5

Former Member
0 Kudos

This message was moderated.

Former Member
0 Kudos

Halo Kalix,

First of all you have to understand that the Subclass will have more attributes/Methods compared to Super Class .

ie when we move a lion object to the Animal object we are reducing its attributes/Methods i.e why it is called Narrow casting.

Use of Narrow casting .

We have a lot of animal reference objects like Cat, Dog,Lion etc inheriting from Animal Class.We can assign all these objects to the super class object Animal . Suppose we have an internal table of type ref to animal class .

We could do something like


Data:  lt_animal type table of ref to lcl_animal.
append lcl_lion to lt_animal.
append lcl_cat to lt_animal.

Now coming to Widening cast , We will have lot of methods which are specific to these subclasses( and not a part of Super Class) . For eg we may have method like attack_prey for lion or play_with_ball for Cat which are not defined in the Super class.You cannot call this method using animal reference objec t. In that case you need to wide cast it to the more speciif classes.



loop at lt_animal into l_animal.

  l_classname = cl_abap_classdescr=>get_class_name( l_animal ).
  l_class_name = l_classname+7(30).
if l_animal = 'LCL_LION'.
l_lion ?= l_animal.
l_lion->attack_prey( ).
elseif l_animal = 'LCL_DOG'.
l_dog ?=  l_animal.
l_dog->play_with_ball( ).
endif.

Regards

Arshad

Private_Member_1084
Active Contributor
0 Kudos

Hello Eti,

I think you're aware of Narrowing & Widening Cast, if not Arshad's response explains these concepts.

... why do we have to assign the instance of lo_animal to lo_lion which is having the same instance of lo_lion( lo_lion & lo_tmp_lion are reference var of same class ) ...

To understand this you need to know - [Static Type|http://help.sap.com/abapdocu_731/en/abenstatic_type_glosry.htm] and [Dynamic Type|http://help.sap.com/abapdocu_731/en/abendynamic_type_glosry.htm] for reference variables. (This applies to both data and object reference variables).

The golden-rule for assignment of reference variables is,

Dynamic type of a ref. variable must always be more specific than the static type.

DATA: lo_animal TYPE REF TO lcl_animal,"Super Class
      lo_lion   TYPE REF TO lcl_lion. "Sub Class

The static type of the ref. variable lo_lion is lcl_lion. Now let's consider this assignment,

lo_lion = lo_animal.

The compiler interprets the dynamic type of lo_lion (after this assignment) would be lcl_animal. It is more generic compared to the static type( lcl_lion ), since lcl_animal is a super-class of lcl_lion, so the compiler will throw a static syntax error. (Remember the "golden-rule" of reference variable assignment)

The [casting operator|http://help.sap.com/abapdocu_731/en/abencasting_operator_glosry.htm] is just an instruction to the compiler to skip the static syntax check during the widening cast,

lo_lion ?= lo_animal. "Widening Cast

.

Always remember that for Widening Casts the "golden-rule" of assignment will be checked during runtime.

If the rule is not satisfied, it'll result in an exception - CX_SY_MOVE_CAST_ERROR ! In order to avoid this situation, the demo program uses a temporary reference variable - lo_tmp_lion.

lo_animal = lo_tmp_lion. "Narrow Casting
lo_lion ?= lo_animal."Widening cast

Sorry for this big post, hope it helps & reduces your confusion

BR,

Suhas

PS: Normally when you're doing a Widening Cast you would not be required to use a temporary ref. variable.

naimesh_patel
Active Contributor
0 Kudos

Casting would be used whenever you want to use the Generic Type e.g. LCL_ANIMAL, CL_ABAP_TYPEDESCR are used to defined the parameter or variables. But they would contains more Specific Type e.g. Reference of LION, or reference of Structure object.

This code was to just set up the data which would be used for Widening cast later on. Assume that this piece of code is in the Perform or method, and LO_ANIMAL is the returning parameter. So, when you create the object LO_TMP_LION and assign it to LO_ANIMAL, at runtime it would still contain the object reference of the LCL_LION.

 
  CREATE OBJECT lo_tmp_lion.
  lo_animal = lo_tmp_lion.                  " Narrow Casting

Similar process happens when you use the method DESCRIBE_BY_NAME of the class CL_ABAP_TYPEDESCR. Returning Parameter P_DESCR_REF is declared with the CL_ABAP_TYPEDESCR. But based on the provided importing parameter P_NAME, the method will generate different type of object references. Since the given name in your example is table type, you are receiving that object reference in the variable defined with the type CL_ABAP_TABLEDESCR. Based on the type of the P_NAME system will generate the object so, it doesnu2019t need to do the narrow casting as what I did in my old and poor example at [ABAP Objects: Widening Cast|http://help-abap.zevolving.com/2008/09/abap-objects-widening-cast/].

@Suhas

Why not to mention golden rule with Golden color

The golden-rule for assignment of reference variables is,

Dynamic type of a ref. variable must always be more specific than the static type.

Regards,

Naimesh Patel

0 Kudos

Hi All...

Thanks a lot for all your quick response.

Suhas's reply to my first question "why do we have to assign...." solved my first doubt and understood the static and dynamic type and onething that i want to confirm is whther i understood correctly or not.

my understanding abt this is,



DATA: lo_animal TYPE REF TO lcl_animal,"Super Class
      lo_lion   TYPE REF TO lcl_lion. "Sub Class     " static type

      lo_lion = lo_animal.        " Dynamic Type

Pls Correct me if i am wrong.

though the reply of naimesh seems bit tough to understand, i referred so many threads to understand his explanation and i finally understood the usage of RTTS in widening from some of his replies in some threads.

Thanks once again naimesh & suhas.