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: 

Classes name decided at runtime

former_member1161170
Participant
0 Kudos

Hi experts.

I have to build a program, or more ones, to get several files which have some little differences among them.

I thought to do a father class with the common fields, and after that to get a son class for each file, filling the other fields.

My opinion is that the best thing is to use a parameter with the final class name, so I would have only one create statement.

I have two parameters in my constructor.

I follow this way:

DATA: istanza TYPE REF TO Zclassname.

[...]

PARAMETERS : t_class1 TYPE zcolt_rf0000-classe

MATCHCODE OBJECT zcolt_rf0000_sort.

[...]

CREATE OBJECT istanza TYPE (t_class1)

EXPORTING

i_selvbeln = s_vbeln[]

i_fkdat = s_fkdat[].

T_class1 contains the name of the class, i_selvblen and ifkdat are two parameters.

I have two problems:

1) When I try to active the class I get the error "You cannot use constructor paramters in a dynamic create object"

2) But really it's an "almost dynamic create object", because I can't declare a generic class. How can I get the Zclassname as the name contained in t_class1? Ho must I declare it?

Thanks for your future helps.

1 ACCEPTED SOLUTION

Sm1tje
Active Contributor
0 Kudos

You have to declare it like this:


DATA: istanza TYPE REF TO object.

11 REPLIES 11

Sm1tje
Active Contributor
0 Kudos

You have to declare it like this:


DATA: istanza TYPE REF TO object.

0 Kudos

>You have to declare it like this:

>DATA: istanza TYPE REF TO object.

Thank you.

I believe this is an answer to the second question.

But I can't see if it's good because It is messaging the error "You cannot use constructor paramters in a dynamic create object"

yet.

0 Kudos

Hi Massimiliano,


...
  lf_class = '_LCL_DUMMY'.
  CREATE OBJECT lo_class TYPE (lf_class)
    EXPORTING  id = '42'.
...

works fine with my example.

At 'ABAP Keyword Documentation' for CREATE OBJECT there was a note that is is possible since release 6.10.

Or you can use the addition PARAMETER-TABLE:


ptab_line-name = 'ID'.
ptab_line-kind = cl_abap_objectdescr=>exporting.
ptab_line-value = dref.
INSERT ptab_line INTO TABLE ptab.

CREATE OBJECT lo_class TYPE (lf_class)
  PARAMETER-TABLE ptab.

regards, Karsten

naimesh_patel
Active Contributor
0 Kudos

As you designed, you can create a Parent class say ZCL_FILE. Make this class abstract. So, you can't instantiate the object of this class. Create a FACTORY method as a Public static method in this class. In the parameters, you can pass the Required Key as the importing parameter and pass back the object. Declare this returning object as the reference to parent class.


METHOD FACTORY.
* parameters"
* IMporting I_FILE_SYSTEM TYPE STRING
* Returning RO_FILE TYPE REF TO ZCL_FILE

  case i_file_system.
    when 'ABC'.
        lf_class_name = 'ZCL_FILE_ABC'.
    when 'XYZ'.
        lf_class_name = 'ZCL_FILE_XYZ'.
  endcase.
  create object RO_FILE type (lf_class_name).
ENDMETHOD.

Inherit your required classes ZCL_FILE_ABC, ZCL_FILE_XYZ by assigning super class as the ZCL_FILE.

In the calling program:


data: lo_file type ref to ZCL_FILE.
LO_FILE = ZCL_FILE=>FACTORY( 'ABC' ).

Regards,

Naimesh Patel

0 Kudos

Hi Naimesh Patel,

why not:


...
  case i_file_system.
    when 'ABC'.
       create object RO_FILE type ZCL_FILE_ABC.
    when 'XYZ'.
       create object RO_FILE type ZCL_FILE_XYZ.
  endcase.
...

Then you don't have the problem with dynamic class-names and constructor-parameters any more.

regards, Karsten

0 Kudos

Yes, we can do that. But it will increase maintenance when you add a new parameter to the constructor. It would not be much but if you have high number for subclasses, than the effort will increase. And also it reduces the Code Noise.

And always, you can try to catch the catchable runtime errors while using the dynamic programming. Like:


CLASS lcl_test DEFINITION.
  PUBLIC SECTION.
    METHODS:
    constructor
     IMPORTING
        if_val TYPE i.
ENDCLASS.                    "lcl_test DEFINITION

DATA: lo_test TYPE REF TO lcl_test.
TRY.
    CREATE OBJECT lo_test
      TYPE
        ('LCL_TEST')
      EXPORTING
        if_val1      = 1.  " IF_VAL is there but not IF_VAL1
  CATCH cx_root .  " <<
ENDTRY.

CLASS lcl_test IMPLEMENTATION.
  METHOD constructor.
  ENDMETHOD.                    "constructor
ENDCLASS.                    "lcl_Test IMPLEMENTATION

Regards,

Naimesh Patel

0 Kudos

Thanks to everybody.

I forgot to specify I have the rel.4.6c.

So I believe to have to pass through the parameter-table, as Karsten says.

I read the manual, I saw several examples, but I can't understand how must I use these table and line:

ptab TYPE abap_parmbind_tab,

ptab_line TYPE abap_parmbind.

Is the following block a parameter?

ptab_line-name = 'what must I write here? Then parameter name in the constructor? Or the parameter name in the caller?'.

ptab_line-kind = cl_abap_objectdescr=>exporting. (Can this method get the right type?)

ptab_line-value = what must I put here? Directly my parameter from selection screen?

INSERT ptab_line INTO TABLE ptab.

About ptab_line-kind I'm getting the error: "Direct access to components of the global class CL_ABAP_OBJECT_DESCR is not possible. (CLASS CL_ABAP_OBJECT_DESCR statement is missing.)"

Is not "exporting" a static method? Have I to do a create an object for the class?

Sorry for so many questions, but I'm a newbie.

Edited by: Massimiliano Beghini 2 on Oct 22, 2009 6:43 PM

0 Kudos

Since you are on older release, you need to use the statement CLASS ... DEFINITION LOAD before accessing any static attribute of the class.


CLASS CL_ABAP_OBJECTDESCR DEFINITION LOAD. 
....
* Specify the parameter of the METHOD which you will call dynamically.
ptab_line-name = 'IF_PAR1'.
* Type of the Parameter, Exporting, Changing, Importing, 
ptab_line-kind = cl_abap_objectdescr=>exporting.
* Pass your data with reference to the Value. E.g. global variant W_PAR1 as:
GET REFERENCE OF W_PAR1 INTO ptab_line-value.
INSERT ptab_line INTO TABLE ptab.

Regards,

Naimesh Patel

former_member1161170
Participant
0 Kudos

I can't understand well yet.

Now I have learned:

1) How declare the generic class (REF TO OBJECT)

2) How use abap_parmbind_tab and abap_parmbind

Very good! I'm almost happy 🐵

The thing I can't understand yet: can I pass the parameters for a constructor or not ?

If I can't: is this a release problem? Must I only use the public static method "Factory" system?

If I can: how can i get it? I'm receving always the messagge "You cannot constructor parameter in a dynamic CREATE OBJECT"

Now the code is:

ptab_line-name = 'i_selvbeln'.

ptab_line-kind = cl_abap_objectdescr=>exporting.

GET REFERENCE OF s_vbeln[] INTO ptab_line-value.

INSERT ptab_line INTO TABLE ptab.

ptab_line-name = 'i_fkdat'.

ptab_line-kind = cl_abap_objectdescr=>exporting.

GET REFERENCE OF s_fkdat[] INTO ptab_line-value.

INSERT ptab_line INTO TABLE ptab.

CREATE OBJECT istanza TYPE (t_class1)

PARAMETER-TABLE ptab.

Thank you for the help you give me until now: I'm learning very much.

0 Kudos

It looks like this is release problem.

Dynamic Parameters in instantiation is avaliable from the ABAP release 6.10

http://help.sap.com/abapdocu_70/en/ABENNEWS-610-OBJECTS.htm#!ABAP_MODIFICATION_5@5@

I guess, you have to go on the FACTORY method route to instantiate the objects. Create an abstract FACTORY method in your Super Class. Redefine it in your Subclass. From your program, use the dynamic call to call the (class_name)=>FACTORY method.

Regards,

Naimesh Patel

kurt_slater3
Explorer
0 Kudos

Message deleted since example cited has already been provided by Karsten.