Object Oriented ABAP - Features and Restrictions.


Constructor cannot call virtual-like methods of a class.

If a method is called from constructor, then always will be called the current class method, not overridden method in virtual-like style.

REPORT ZVV0002.
*----------------------------------------------------------------------*
class c_base definition.
  public section.
    methods:    constructor,
                m_ad,
                m_introduce.
endclass.
*----------------------------------------------------------------------*
class c_derived definition inheriting from c_base.
  public section.
    methods:    constructor,
                m_ad redefinition.
endclass.
*----------------------------------------------------------------------*
class c_base implementation.
  method constructor.
    call method m_ad.
  endmethod.
  method m_ad.
    write / 'I am BASE...'.
  endmethod.
  method m_introduce.
    call method m_ad.
  endmethod.
endclass.
*----------------------------------------------------------------------*
class c_derived implementation.
  method constructor.
    call method: super->constructor.
  endmethod.
  method m_ad.
    write / 'I am DERIVED'.
  endmethod.
endclass.
*----------------------------------------------------------------------*
data o_1 type ref to c_base.
*----------------------------------------------------------------------*
END-OF-SELECTION.
*----------------------------------------------------------------------*
write / '      BASE OBJECT:'.
create object o_1 type c_base.
call method o_1->m_introduce.
write / '      DERIVED OBJECT:'.
create object o_1 type c_derived.
call method o_1->m_introduce.

      BASE OBJECT:
I am BASE...
I am BASE...
      DERIVED OBJECT:
I am BASE...
I am DERIVED

Returning method can be used only in expressions.

If a method only has IMPORTING parameters and one RETURNING parameter (aka functional method), it can be used as an operand in an expression, but it cannot be used in statements like WRITE etc.

REPORT ZVV0003.
*----------------------------------------------------------------------*
class c_time definition.
  public section.
    methods: constructor,
             get_time returning value(p_time) like sy-uzeit.
  private section.
    data     a_time like sy-uzeit.
endclass.
class c_time implementation.
  method constructor. a_time = sy-uzeit.   endmethod.
  method get_time.    p_time = a_time.     endmethod.
endclass.
*----------------------------------------------------------------------*
data: o_1    type ref to c_time,
      w_time like sy-uzeit.
END-OF-SELECTION.
create object o_1.
* write / o_1->get_time( ).                          "Error!
w_time = o_1->get_time( ).        write / w_time.    "Ok
w_time = o_1->get_time( ) + 5.    write / w_time.    "Ok

13:14:50
13:14:55

Private components of a class.

If a method uses private components of the class, and this method is not redefined and being called from a subclass, it will always use the private components of the superclass, even if the subclass has its own private components of the same name.

REPORT ZVV0002.
*----------------------------------------------------------------------*
class c_base definition.
  public section.
    methods: constructor importing value(p_name) type string,
             m_show1,
             m_show2.
  private section.
    data     a_name type string.
endclass.
*----------------------------------------------------------------------*
class c_derived definition inheriting from c_base.
  public section.
    methods: constructor importing value(p_name1) type string
                                   value(p_name2) type string,
             m_show1 redefinition.
  private section.
    data     a_name type string.
endclass.
*----------------------------------------------------------------------*
class c_base implementation.
  method constructor.
    a_name = p_name.
  endmethod.
  method m_show1.
    write: / 'Show1  :', a_name.
  endmethod.
  method m_show2.
    write: / 'Show2  :', a_name.
  endmethod.
endclass.
*----------------------------------------------------------------------*
class c_derived implementation.
  method constructor.
    call method: super->constructor exporting p_name = p_name1.
    a_name = p_name2.
  endmethod.
  method m_show1.
    write: / 'Show1_r:', a_name.
  endmethod.
endclass.
*----------------------------------------------------------------------*
data o type ref to c_derived.
*----------------------------------------------------------------------*
END-OF-SELECTION.
*----------------------------------------------------------------------*
create object o exporting p_name1 = 'Base...' p_name2 = 'Derived...'.
call method: o->m_show1,
             o->m_show2.
*----------------------------------------------------------------------*

Show1_r: Derived...
Show2  : Base...

Widening and narrowing cast.

In fact, narrowing and widening casts only change object view to less or more detailed, switching the reference variable that points to the object. Real object is not changed by both casts. It's forbidden to assign object reference to subclass object reference even using widening cast, for example, initializing the extra components with their default values. System-exception move_cast_error will be raised.

REPORT ZVV0003.
*----------------------------------------------------------------------*
class c_base definition.
  public section.
    methods: constructor importing value(p_name) type string,
             m_show.
    data     a_name1 type string.
endclass.
*----------------------------------------------------------------------*
class c_derived definition inheriting from c_base.
  public section.
    methods: constructor importing value(p_name1) type string
                                   value(p_name2) type string,
             m_show redefinition.
    data     a_name2 type string.
endclass.
*----------------------------------------------------------------------*
class c_base implementation.
  method constructor.
    a_name1 = p_name.
  endmethod.
  method m_show.
    write: / 'Base:', a_name1, '.'.
  endmethod.
endclass.
*----------------------------------------------------------------------*
class c_derived implementation.
  method constructor.
    call method: super->constructor exporting p_name = p_name1.
    a_name2 = p_name2.
  endmethod.
  method m_show.
    write: / 'Derived:', a_name1, ',', a_name2, '.'.
  endmethod.
endclass.
*----------------------------------------------------------------------*
data: o_1a type ref to c_base,
      o_1b type ref to c_base,
      o_2a type ref to c_derived,
      o_2b type ref to c_derived.
*----------------------------------------------------------------------*
END-OF-SELECTION.
*----------------------------------------------------------------------*
create object: o_2a exporting p_name1 = 'First' p_name2 = 'Second',
               o_1a exporting p_name  = '=1st='.
o_1b = o_2a.                                      "no problem
call method: o_1a->m_show,
             o_2a->m_show,
             o_1b->m_show.
catch system-exceptions move_cast_error = 4.
  o_2b ?= o_1a.                                   "impossible
endcatch.
if sy-subrc = 4.   write / 'Cannot cast o_2b ?= o_1a.'.
else.              call method o_2b->m_show.
endif.
catch system-exceptions move_cast_error = 4.
  o_2b ?= o_1b.                                   "only casting possible
endcatch.
if sy-subrc = 4.   write / 'Cannot cast o_2b ?= o_1b.'.
else.              call method o_2b->m_show.
endif.
*----------------------------------------------------------------------*

Base: =1st= .
Derived: First , Second .
Derived: First , Second .
Cannot cast o_2b ?= o_1a.
Derived: First , Second .

Constructor - optional and default parameters.

Each class has only one instance constructor, which cannot be overloaded. But, using optional and default parameters allows seeming overloading.

report z.

class w_test definition.
  public section.
    methods:
      constructor
        importing value(p_name) type string optional
                  value(p_date) like sy-datum default sy-datum,
      show.
  private section.
    data:
      name type string,
      date like sy-datum.
endclass.

class w_test implementation.
  method constructor.
    name = p_name.
    date = p_date.
  endmethod.
  method show.
    write: / date, name.
  endmethod.
endclass.

data: w1 type ref to w_test,
      w2 like w1, w3 like w1.

END-OF-SELECTION.
* use different variants of creating the object instance:
create object w3.
create object w2 exporting p_name = '2nd'.
create object w1 exporting p_date = '20011115' p_name = '1st'.

call method: w1->show, w2->show, w3->show.

11/15/2001 1st
10/31/2001 2nd
10/31/2001

See also:


TopList 1