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: 

ABAP Polymorphism Problem

Former Member
0 Kudos
170

Hello All!

I am running into a problem of type compatibility when I declare a parameter of a subroutine as an abstract superclass and try to pass through a subclass. According to the documentation I have read, this should work (it also works in many other OOP languages). Furthermore, I attempted to create a field symbol of the superclass and assign the subclass to it, then pass it through to the subroutine, but the type incompatability error occurred there as well. This leads me to believe it is a problem with my declaration of the classes, but they seem alright. I am going to post example code in the following post.

Please examine and let me know if I am doing anything weird/wrong.

Thank you,

Steven Coolbaugh

1 ACCEPTED SOLUTION

naimesh_patel
Active Contributor
0 Kudos
77

You need to do the casting to the super's reference and use this object in the parameter of your Subroutine.

Like:


*----------------------------------------------------------------------*
*       CLASS lcl_super DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_super DEFINITION ABSTRACT.

  PROTECTED SECTION.
    DATA: f_num1 TYPE i.

ENDCLASS.                    "lcl_super DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_sub DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_sub DEFINITION INHERITING FROM lcl_super.

  PUBLIC SECTION.
    METHODS:
      set_f_num1
        IMPORTING
          if_num TYPE i,
      get_f_num1
        RETURNING
          value(rf_num) TYPE i.

ENDCLASS.                    "lcl_sub DEFINITION

START-OF-SELECTION.
  DATA: o_super TYPE REF TO lcl_super,
        o_sub   TYPE REF TO lcl_sub.

  CREATE OBJECT o_sub.

  o_sub->set_f_num1( 10 ).
  o_super = o_sub.                     " Down Casting
  PERFORM get_f_num USING o_super.

*&---------------------------------------------------------------------*
*&      Form  get_f_num
*&---------------------------------------------------------------------*
FORM get_f_num USING io_super TYPE REF TO lcl_super.

  DATA: lo_sub TYPE REF TO lcl_sub,
        lf_num TYPE i.

  lo_sub ?= io_super.      " Up Casting

  lf_num = lo_sub->get_f_num1( ).
  WRITE: lf_num.

ENDFORM.                    "get_f_num

*----------------------------------------------------------------------*
*       CLASS lcl_sub IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_sub IMPLEMENTATION.

  METHOD set_f_num1.
    me->f_num1 = if_num.
  ENDMETHOD.                                                "set_F_num1

  METHOD get_f_num1.
    rf_num = me->f_num1.
  ENDMETHOD.                                                "get_f_num1

ENDCLASS.                    "lcl_sub IMPLEMENTATION

Regards,

Naimesh Patel

5 REPLIES 5

naimesh_patel
Active Contributor
0 Kudos
78

You need to do the casting to the super's reference and use this object in the parameter of your Subroutine.

Like:


*----------------------------------------------------------------------*
*       CLASS lcl_super DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_super DEFINITION ABSTRACT.

  PROTECTED SECTION.
    DATA: f_num1 TYPE i.

ENDCLASS.                    "lcl_super DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_sub DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_sub DEFINITION INHERITING FROM lcl_super.

  PUBLIC SECTION.
    METHODS:
      set_f_num1
        IMPORTING
          if_num TYPE i,
      get_f_num1
        RETURNING
          value(rf_num) TYPE i.

ENDCLASS.                    "lcl_sub DEFINITION

START-OF-SELECTION.
  DATA: o_super TYPE REF TO lcl_super,
        o_sub   TYPE REF TO lcl_sub.

  CREATE OBJECT o_sub.

  o_sub->set_f_num1( 10 ).
  o_super = o_sub.                     " Down Casting
  PERFORM get_f_num USING o_super.

*&---------------------------------------------------------------------*
*&      Form  get_f_num
*&---------------------------------------------------------------------*
FORM get_f_num USING io_super TYPE REF TO lcl_super.

  DATA: lo_sub TYPE REF TO lcl_sub,
        lf_num TYPE i.

  lo_sub ?= io_super.      " Up Casting

  lf_num = lo_sub->get_f_num1( ).
  WRITE: lf_num.

ENDFORM.                    "get_f_num

*----------------------------------------------------------------------*
*       CLASS lcl_sub IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_sub IMPLEMENTATION.

  METHOD set_f_num1.
    me->f_num1 = if_num.
  ENDMETHOD.                                                "set_F_num1

  METHOD get_f_num1.
    rf_num = me->f_num1.
  ENDMETHOD.                                                "get_f_num1

ENDCLASS.                    "lcl_sub IMPLEMENTATION

Regards,

Naimesh Patel

0 Kudos
77

Naimesh,

Thank you very much. I removed the ABSTRACT verbage from the Superclass Definition and the Method Declaration, then cast the subclass to a superclass reference before the call and it worked.

The vast majority of my experience is in VC++ and VB, so I was used to declaring formal parameters as superclasses and just sending subclasses through.

On a side note, I would like to thank you for your posts I have found online (Both on and off this site). It seems like whenever I have a question/problem, google comes back with a post by you that has a very thorough explanation of my question/problem. Thank you and keep up the good work!

Steven Coolbaugh

0 Kudos
77

Naimesh,

Thank you very much. I removed the ABSTRACT verbage from the Superclass Definition and the Method Declaration, then cast the subclass to a superclass reference before the call and it worked.

The vast majority of my experience is in VC++ and VB, so I was used to declaring formal parameters as superclasses and just sending subclasses through.

On a side note, I would like to thank you for your posts I have found online (Both on and off this site). It seems like whenever I have a question/problem, google comes back with a post by you that has a very thorough explanation of my question/problem. Thank you and keep up the good work!

Steven Coolbaugh

0 Kudos
77

Thanks for your compliments..!

You don't need to remove the ABSTRACT from the SUPER Class definition. ABSTRACT will only stop if you try to create an instance of that class. But if you have an instance created (of a subclass) and you are assigning that instance to the Object Reference which is declared with reference to the Abstract Super Class, it wont stop you.

Regards,

Naimesh Patel

0 Kudos
77

Ah, once again my previous experience is causing problems. In C++, declarations of pointers to an object have a different declaration from object variable declarations. I keep forgetting that ABAP uses reference variables exclusively, therefore the object is not instanced (although had I thought about it, CREATE OBJECT would not need to be used if it worked otherwise). Thank you for the correction.

On a different note, I did not have to up cast the passed super object to the sub object; which is very good, since I am passing many different subclasses through to this subroutine.

Once again, thank you for your help.