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

Convert object type in another object (OO programming)

Former Member
0 Likes
3,531

Hi Forum,

I have a problem to solve but i dont know how. I have a standar report and i need to insert some modifications...for my bussines requeriments.

I have this type:

DATA gr_acc              TYPE REF TO object.

So my problem is that i need to access to a method of this object ( in dinamic mode this object is this class: CL_PRWB_ACCESS_LINK_UI, and when i try to access to method, for example: GET_SELECTED_ROWS, i cant because is unkown, protected or private.

My solution is to create another object for example this:

DATA gr_acc1            TYPE REF TO CL_PRWB_ACCESS_LINK_UI.

But when i try to convert to my type i cant.....

GET REFERENCE OF GR_ACC INTO GR_ACC1.

Because it is not compatible...

How can i access to a method of this generic abap type or convert this data for my propuse¿?

Regards and thanks in advance,

Mon

Edited by: Peruches on Jun 1, 2009 5:35 PM

1 ACCEPTED SOLUTION
Read only

MarcinPciak
Active Contributor
0 Likes
1,988

Hi,

If you already have reference of class CL_PRWB_ACCESS_LINK_UI in gr_acc you can access its method dynamically with


data: method_name(17) type c value 'GET_SELECTED_ROWS'.

"you call method as it would be static call, only difference is that you determine methods name during runtime 
call method gr_acc->(method_name)
    exporting ...
    importing ...

or statically with


DATA gr_acc              TYPE REF TO object.
DATA gr_acc1            TYPE REF TO CL_PRWB_ACCESS_LINK_UI.

gr_acc1 ?= gr_acc.  "here you never know what real type of OBJECT is therefore you have to use down cast ?= operator

"now you can call the method statuically as gr_acc1 us typed with your class and system recognize it during syntax check
call method gr_acc1->get_selected_rows
      exporting ..
      importing....

Here some explanation. An object class is a root class in inheritance hierarchy (which means all subordinate classes inherit from that one), therefore if you want to assing its reference to any of subordinate class you need to use down cast operator (?=).

Now some explanations:

Image that you have a VEHICLE (our object class). Now you have subordinate class - a PLAIN (here our CL_PRWB_ACCESS_LINK_UI class).

Now when you do assignment between classes you have to take following under consideration:

1) is PLAIN always a VEHICLE ?

2) is VEHICLE always a PLAIN ?

First question is easy. It is always true. But the second not necessarly. The VEHICLE can be i.e. a CAR, a TRUCK, a SHIP etc. This is how we do an assignment:


data: r_vehicle type ref to vehicle,
         r_plain type ref to plain.

create object r_plain.

"first case 
r_vehicle = r_plain.   

"second case
r_plain ?= r_vehicle. "static type of r_vehicle is VEHICLE, but dynamica type is PLAIN, so the assignment is possible

"but if you do such thing
data: r_car type ref to car.

r_vehicle = r_car.
r_plain ?= r_vehicle.  "the system will dump out, because dynamic type of r_vehicle is CAR, not a PLAIN

This is why we need to use down cast operator. BTW: what we did here


r_vehicle = r_plain.   

is called up cast which is swithing from more detail view to more general one.

Castng is one of basics of polimorphism, which is the most powerful methodology in OO programing. I recommend you go through some SAP documentation to deepen the topic.

Regards

Marcin

11 REPLIES 11
Read only

Former Member
0 Likes
1,988

Hi,

Instead of getting referance why don't you try like this ,



gr_acc1 = gr_acc

.

And while accessing the methods , you need to sure about what kind of method you are accessing to like is it an instataneous object or a static object, and then access it accordingly.

Because if you are trying to access a static method by an instantaneous method call, then you are going to have a syntax error saying method does not exists.This implies to the objects also.

Hope this helps you.

Regards,

Abhinab Mishra

P.S : This may not be a correct solution as I am still at the learning stage of ABAP OO.

Read only

MarcinPciak
Active Contributor
0 Likes
1,989

Hi,

If you already have reference of class CL_PRWB_ACCESS_LINK_UI in gr_acc you can access its method dynamically with


data: method_name(17) type c value 'GET_SELECTED_ROWS'.

"you call method as it would be static call, only difference is that you determine methods name during runtime 
call method gr_acc->(method_name)
    exporting ...
    importing ...

or statically with


DATA gr_acc              TYPE REF TO object.
DATA gr_acc1            TYPE REF TO CL_PRWB_ACCESS_LINK_UI.

gr_acc1 ?= gr_acc.  "here you never know what real type of OBJECT is therefore you have to use down cast ?= operator

"now you can call the method statuically as gr_acc1 us typed with your class and system recognize it during syntax check
call method gr_acc1->get_selected_rows
      exporting ..
      importing....

Here some explanation. An object class is a root class in inheritance hierarchy (which means all subordinate classes inherit from that one), therefore if you want to assing its reference to any of subordinate class you need to use down cast operator (?=).

Now some explanations:

Image that you have a VEHICLE (our object class). Now you have subordinate class - a PLAIN (here our CL_PRWB_ACCESS_LINK_UI class).

Now when you do assignment between classes you have to take following under consideration:

1) is PLAIN always a VEHICLE ?

2) is VEHICLE always a PLAIN ?

First question is easy. It is always true. But the second not necessarly. The VEHICLE can be i.e. a CAR, a TRUCK, a SHIP etc. This is how we do an assignment:


data: r_vehicle type ref to vehicle,
         r_plain type ref to plain.

create object r_plain.

"first case 
r_vehicle = r_plain.   

"second case
r_plain ?= r_vehicle. "static type of r_vehicle is VEHICLE, but dynamica type is PLAIN, so the assignment is possible

"but if you do such thing
data: r_car type ref to car.

r_vehicle = r_car.
r_plain ?= r_vehicle.  "the system will dump out, because dynamic type of r_vehicle is CAR, not a PLAIN

This is why we need to use down cast operator. BTW: what we did here


r_vehicle = r_plain.   

is called up cast which is swithing from more detail view to more general one.

Castng is one of basics of polimorphism, which is the most powerful methodology in OO programing. I recommend you go through some SAP documentation to deepen the topic.

Regards

Marcin

Read only

Former Member
0 Likes
1,988

I donot think so that u would be able to use this bcoz this is private.

U can only call a method or attribute of Private/Protected class only by the instance of the class which uses/instantiate ur private class.

The only way to do this is to call some method of another class which instantiate this object.

Regards,

Rajiv

Read only

Former Member
0 Likes
1,988

Hi Abhinab Mishra,

I try to asign directly this:

gr_acc1 = gr_acc.

and dont work. Thanks

Read only

Former Member
0 Likes
1,988

Hi Marcin,

Finally I use yoy solution:

Dinamic mode:

data: method_name(17) type c value 'GET_SELECTED_ROWS'.
 
"you call method as it would be static call, only difference is that you determine methods name during runtime 
call method gr_acc->(method_name)
    exporting ...
    importing ...

Works perfectly.

Thanks and regards!

Mon

Read only

Former Member
0 Likes
1,988

Hi again,

One question more. How can i access to an attribute?

For example:

data attribute(15) type c value 'GV_SOURCE_GUID'.
gr_acc1 ?= gr_acc.

** guid:
guid1 = gr_acc1->(attribute). " not work

Regards and thanks.

Mon

Read only

0 Likes
1,988

Hi,

Here you should use static access, as no dynamic one for attributes exists. So litte correction:


gr_acc1 ?= gr_acc.
 
guid1 = gr_acc1->GV_SOURCE_GUID. " now should work:)

Note that you can address it statically because you use gr_acc1 whose static type is your class cl_...

So the compilator recognizes it during syntax check. But during runtime, gr_acc1 can contain different dynamic type.

Generally: for compilator static type is important, for runtime environment dynamic one.

Regards

Marcin

Edited by: Marcin Pciak on Jun 2, 2009 11:16 AM

Read only

Former Member
0 Likes
1,988

Hi Marcin.

In this case, i cant...error:

Access to protectd attribute "GV_SOURCE_GUID" is not allowed.

Regards!

Read only

0 Likes
1,988

If an attribute is proteced you can't access it from outside the class, but you can create your custom class which inherits from this class and here all protected attributes are visible.

This is a trick which allows you to enlarge visibility section outside the class itself, but is not a good practise.

If an attribute is protected it means it was intended not to be changed form outside. It is most likely that there is some method which allows to change this attribute, but not directly by accessing it - so please first look for one.

This is important, as the state of your object can become inconsistent when you just change attributes from outside.

If you just want to read it and don't find appropriate method for this task, use the approach explained above. This could be coded like:


"you class which inherits from the above one
class lcl_myclass definition inheriting from CL_PRWB_ACCESS_LINK_UI.
   public section.
     "to read attribute we will use functional method (so the one which returns some value)
     methods: read_attribute  importing class_ref   "we pass reference to above class here
                                             returning value(attr_value).   "parameter must be returned by VALUE not REFERENCE (which is by default)
 
endclass.

"now implementation
class lcl_myclass implementation.
   method read_attribute.
      "here you can access PROTECTED attributes of cl_... class
      if class_ref is bound. "check if contains some object reference
             attr_value = class_ref->GV_SOURCE_GUID.  "this way our method returns attribute value
     endif.
   endmethod.
endclass.

"now how we call it

"first create your object normaly
gr_acc1 ?= gr_acc.

"then create an object of our new class
data: gr_myclass type ref to lcl_myclass.

create object gr_myclass.

"and get attribute by means of our new method
guid1 = gr_myclass->read_attribute( class_ref = gr_acc1 ).  "we pass gr_acc1 reference so inside the method we read its attribute

That's all you need

Regards

Marcin

Read only

Former Member
0 Likes
1,988

Hi Marcin again,

Sorry to border you again...but when i try to define the firts class it apears an error:

The final class "CL_PRWB_ACCESS_LINK_UI" cannot have any subclasses.

Regards and thanks...

Mon

Read only

0 Likes
1,988

Hi again Mon,

Unfortunatelly if the class is final, you can't derive any new classes from it, therefore there is no way you can access this protected attribute. You must look for a method which allows that. Otherwise you can't.

What I recommend you is go to se24->type in your class->Display->Attributes->place cursor on GV_SOURCE_GUID -> choose WHERE USED icon in application toolbar ->. leave only selection Classes . Now you have listed all classes and methods where it is used. Review them (only methods of your class) and try to deduct which might return value of that attribute. It can also be that, none of them do that.

Sorry, as I told you. Classes in order to stay consistent musn't be handled from the outside. The solution I gave you in last post, is just and overcoming way, though is not a good practice.

Regards

Marcin