2013 Jan 26 1:04 PM
*&---------------------------------------------------------------------*
*& This code snippet implements the local calss ANIMAL and LION
*&---------------------------------------------------------------------*
REPORT ztest_narrow_casting.
*
*----------------------------------------------------------------------*
* Animal Super Class defintion
*----------------------------------------------------------------------*
CLASS lcl_animal DEFINITION.
PUBLIC SECTION.
METHODS: hungry.
ENDCLASS. "lcl_animal DEFINITION
*
*----------------------------------------------------------------------*
* Lion subclass defintion
*----------------------------------------------------------------------*
CLASS lcl_lion DEFINITION INHERITING FROM lcl_animal.
PUBLIC SECTION.
METHODS: hungry REDEFINITION,
fasting.
ENDCLASS. "lcl_lion DEFINITION
*
*
*----------------------------------------------------------------------*
* Animal Implementation
*----------------------------------------------------------------------*
CLASS lcl_animal IMPLEMENTATION.
METHOD hungry.
WRITE: / 'An animal is hungry'.
ENDMETHOD. "hungry
ENDCLASS. "lcl_animal IMPLEMENTATION
*
*----------------------------------------------------------------------*
* Lion subclass implementation
*----------------------------------------------------------------------*
CLASS lcl_lion IMPLEMENTATION.
METHOD hungry.
WRITE: / 'A Lion (King of Jungle) is hungry.',
'Run as fast as you can..!'.
ENDMETHOD. "hungry
METHOD fasting.
WRITE: / 'Stop running. Lion is on Fasting today.'.
ENDMETHOD.
ENDCLASS. "lcl_lion IMPLEMENTATION
*----------------------------------------------------------------------*
* This code shows how to use the Narrow casting
*----------------------------------------------------------------------*
START-OF-SELECTION.
DATA: lo_animal TYPE REF TO lcl_animal,
lo_lion TYPE REF TO lcl_lion.
*
* ANIMAL object without NARROW casting
WRITE: / 'Animal - without NARROW casting'.
CREATE OBJECT lo_animal.
CALL METHOD lo_animal->hungry( ).
CLEAR lo_animal.
*
* ANIMAL object with NARROW CASTING
SKIP 2.
WRITE: / 'Animal - NARROW casting from LION'.
CREATE OBJECT lo_lion.
lo_animal = lo_lion.
CALL METHOD lo_animal->hungry( ).
*
* call the method FASTING must be a dynamic because FASTING is not
* in the Animal
CALL METHOD lo_animal->('FASTING').
my program is going dump as shown in the following picture:
2013 Jan 26 2:59 PM
The correct way to call the fasting method would
lo_animal->fasting( ).
2013 Jan 27 2:41 AM
* calling the method FASTING must be a dynamic because FASTING is not in the Animal.
so i called like this
CALL METHOD lo_animal->('FASTING').
is there anything wrong ?
2013 Jan 28 3:31 AM
Oh, sorry I didn't notice. But still, that's not the way to call a method in ABAP. If you give a literal within parentheses for a method, it is considered as an input to the method.
I see that you have downcast (or narrow cast) lion object to animal. When you downcast, you cannot call methods that belong specifically to the subclass but you can only call methods which are available at the superclass level. Yes, it's another thing that if a particular method has been redefined in the subclass, the implementation from the subclass will be called.
2013 Jan 26 3:08 PM
Hi erp,
i copy your code and its running successfully in my system............ when you use call method then no need to write ( ).. it uses mainly object->m1().
Regards
Sabyasachi
2013 Jan 27 4:51 AM
2013 Jan 27 7:00 AM
Hi,
start-of-selection.
Data: obj type ref to c1.
create object obj.
use :
call method obj->m1. [m1 is a method of class c1.]
or
obj->m1().
Regards
Sabyasachi
2013 Jan 26 3:52 PM
Hi ERP,
The program goes to dump because the super class object(lo_animal) which is narrow casted cannot access the methods which are implemented only in the subclass.
Please read the below comments on narrow casting. They might help you
Accessing methods using super class reference.
1. By the super class reference (lo_animal) it is possible to access all the methods which are defined at the super class but the implementations are taken from the sub class.
2. If any method is redefined at the sub class then that method’s implementation which exist at the sub class is taken in to consideration.
E.g. Method ‘fasting’ is redefined at the sub class.
When this method is accessed using the super class reference
Like:
Call method lo_animal->fasting.
Here we can access the implementation which exists at the sub class but not from the super class.
3. It is not possible to access the methods which only defined in the sub class using the super class reference.
E.g. fasting is not accessed using reference lo_animal
Call method lo_animal->fasting.
Hope this helps
2013 Jan 27 4:46 AM
i agree with your first point.
as per your second point i have not defined method fasting in super class.
It has been defined in subclass(lcl_lion) only .
as per your third point
i want to call the method FASTING must be a dynamic because FASTING is not in the Animal class.
so i called like this
CALL METHOD lo_animal->('FASTING').
is there anything wrong ?
2013 Jan 28 4:57 AM
Hi ERP,
I am sorry for the slight confusion.
I wanted to say that you cannot access the methods which are defined in subclass only
E.g. Method ‘fasting’ is defined at the sub class level only.
So you cannot call this method using the superclass object reference lo_animal(even after narrow casting).
i want to call the method FASTING must be a dynamic because FASTING is not in the Animal class.
Could you please explain what did you mean by calling dynamically??
2013 Jan 28 10:43 PM
Hi,
the dynamic CALL METHOD is not needed and it won't work on an [animal] reference.
If a [lion] object was created with a reference to an [animal] class, e.g. like this:
CREATE OBJECT lo_animal TYPE lcl_lion.
then the 'simple' way to get a [lion] reference would be:
DATA lo_lion TYPE REF TO lcl_lion.
lo_lion ?= lo_animal. "<< an exception occurs if [animal] is not a [lion].
lo_lion->fasting( ) " now you can call the method..
hope this helps,
JNN
2013 Feb 01 10:23 AM
Hi,
What you have done in second case i.e lo_animal = lo_lion , its widening cast not narrow cast.
Static type lists the method which the reference can access.
Dynamic type tells the implementation to use.
DATA lo_animal TYPE REF TO lcl_animal "static type of lo_animal declared as lcl_animal
DATA lo_lion TYPE REF TO lcl_lion "static type of lo_lion declared as lcl_lion
Now,
lo_animal can only access methods and attributes declared in class lcl_animal and
lo_lion can only access methods and attributes declared in class lcl_lion.
lo_animal = lo_lion "dynamic type of lo_animal declared as lo_lion. ( its a widening cast as you are passing reference of subclass to superclass )
So,
lo_animal will now use implementations from class lcl_lion but only for methods and attributes listed in class lcl_animal.
lo_animal->hungry( ). "its correct as method hungry( ) is listed in class lcl_animal and " implementation used is of class lcl_lion.
lo_animal->fast( ). "its INCORRECT because no method fast( ) is listed in class lcl_animal.
Therefore you are getting that dump.
Once again,
With a reference to an object, after a widening cast you can only and only access the methods and attributes that are listed in its static type.
2013 Feb 01 11:00 AM
I'm on ABAP Release 731 & the OP's code works fine for me, i don't get any exceptions. As per SAP documentation we can use the dynamic method construct to access the methods of the dynamic type:
Alternative 2
... cref->(meth_name) ... .
Effect
This form is possible for all visible methods of objects. cref can be any class reference variable that points to an object that contains the method specified in meth_name. This method is searched for first in the static type, then in the dynamic type of cref
Ref.: http://help.sap.com/abapdocu_731/en/abapcall_method_meth_ident_dyna.htm#!ABAP_ALTERNATIVE_2@2@
I see from the screenshot posted by the OP that the method name is in lower-case. I use the same call with the method name in UPPER-case & works fine for me
TRY .
CALL METHOD lo_animal->('FASTING').
CATCH cx_sy_dyn_call_error INTO lx_dyn_call_err.
lv_msg_txt = lx_dyn_call_err->get_text( ).
MESSAGE lv_msg_txt TYPE 'I'.
ENDTRY.
Imo you should try to handle the exception when dealing with dynamic programming
BR,
Suhas
2013 Feb 01 1:16 PM
Hi Suhas,
I tried executing the above code and it worked for me too. I am on the same release version as yours.
Just had a query.
The dump erp sap is getting, is this just due to lower versions of the system or can be because of any other reason??
2013 Feb 01 4:57 PM
I am not sure about his ABAP release, but in the dump screenshot he has provided you can see that the method name is in lower-case. I think this is the reason why he got a runtime error!
2013 Feb 01 5:08 PM
2013 Feb 01 5:15 PM
Hi Suhas,
Thanx for the reply!!
And maybe the issue is not due to the case of the method name. Maybe it is due to ABAP release.
I found the source of the code from where it was copied. You can check the below link
2013 Feb 01 5:50 PM
Ashish Rawat wrote:
ABAP is NOT case-sensitive !!
- I am not sure which ABAP you're talking about! But the one i know of states & i quote -
These names are used to specify methods dynamically. meth_name and class_name expect character-like fields, which must contain the name of a method or a class in uppercase when the statement is executed.
Ref.: http://help.sap.com/abapdocu_731/en/abapcall_method_meth_ident_dyna.htm
Get your facts straight & try to read the SAP documentation once before giving your valuable comment!
- Execute this piece of code & check the result!
TRY .
CALL METHOD lo_animal->('fasting').
CATCH cx_sy_dyn_call_error INTO lx_dyn_call_err.
lv_msg_txt = lx_dyn_call_err->get_text( ).
MESSAGE lv_msg_txt TYPE 'I'.
LEAVE LIST-PROCESSING.
ENDTRY.
BR,
Suhas
2013 Feb 01 5:53 PM
Hey man!!
Really thanx for the piece of information
Got to learn something new from this!!
2013 Feb 01 7:48 PM
What i meant was statements and keywords are NOT case sensitive.
What you are showing is a 'text literal' which is case sensitive.
That is the rule of passing method name to that method - "If passed as a text literal it should be in UPPERCASE."
2013 Feb 01 10:29 PM
I observed that , strange that it was missed , I too thought it could not be an issue . I guess this is a way of fooling the compiler, but personallyin my opirion, the OP's implementation is a gross misuse of the feature .It has made me think, what could be a scenario to use it. ( Maybe a possible dynamic chain of dynamic method calls ).I would think there are other better uses too.
On the downside, I guess there would severe maintenance impacts, for instance, a where used list of the method would not return any results, usage of obsolete methods etc.
I'm on ABAP Release 731
Lucky you .
Thanks,
Venkat
2013 Feb 01 11:07 AM
Hi,
call method like this:
CALL METHOD lo_animal->FASTING( )
or
lo_animal->fasting( ).