Quantcast
Channel: SCN: Message List
Viewing all articles
Browse latest Browse all 8065

Re: Factories and Inheritance

$
0
0

Hi Emir,

I was just tring to complete an example using an Abstract class before changing all my code and then came across something pretty weird.

 

If I call an instance method in a constructor and then redefine that instance method in a subclass, the redefined method will never be called.  Take a look at the following and let me know what you think.

 

*&---------------------------------------------------------------------*

*& Report  ZKP_TEST3

*&

*&---------------------------------------------------------------------*

*&

*&

*&---------------------------------------------------------------------*

 

REPORT  zkp_test3.

 

*----------------------------------------------------------------------*

*       CLASS mysuper DEFINITION

*----------------------------------------------------------------------*

* Create as abstract so only subclasses can be used create class

* instances

* Create all your inheritable functionality as instance methods

* using the scope to expose specific functionality to subclasses (Protected)

* or classes outside of the class heirarchy (Public)

*----------------------------------------------------------------------*

CLASS mysuper DEFINITION ABSTRACT.

  PUBLICSECTION.

    METHODS: constructor,

             get_my_text RETURNING value(re_text)TYPE string.

 

    " These methods will be visible in all subclasses

  PROTECTEDSECTION.

    METHODS: initialise,

             set_text IMPORTING im_text TYPE string.

 

    " Class Specific Instance

  PRIVATESECTION.

    DATA: mytext TYPE string.

ENDCLASS.                    "mysuper DEFINITION

 

*----------------------------------------------------------------------*

*       INTERFACE createable

*----------------------------------------------------------------------*

* Use this interface to expose a factory method to create an instance of

* a subclass.

*

* Once a class implements this it will no longer be possible to inherit

* from it or all subclasses will inherit these static methods

* that cannot be redefined

*----------------------------------------------------------------------*

INTERFACE createable.

  " This interface is tightly coupled to all instances of mysuper

  " and can be used to create subclasses of this class

  " You could have an import param with type ref to data here,

  " which could be used to dynamically set import params

  CLASS-METHODS: create RETURNING value(re_obj)TYPEREFTO mysuper.

ENDINTERFACE.                    "createable

 

*----------------------------------------------------------------------*

*       CLASS mysub DEFINITION

*----------------------------------------------------------------------*

* Defined as final as subclasses cannot be redefined and should not

* inherit static factory methods because class type is defined explicitly

* in method (see im_type)

*----------------------------------------------------------------------*

CLASS mysub DEFINITION INHERITING FROM mysuper CREATEPRIVATEFINAL.

  PUBLICSECTION.

    INTERFACES: createable.

 

  PROTECTEDSECTION.

    " Redefined method in subclass to do something more specific

    METHODS: initialise REDEFINITION,

             constructor.

ENDCLASS.                    "mysub DEFINITION

 

DATA: go_super TYPEREFTO mysuper,

      l_text   TYPE string.

 

START-OF-SELECTION.

 

  " Instantiation of instances of mysub only possible via this static public method

  go_super = mysub=>createable~create().

 

  " Method get_my_text is inherited

  l_text = go_super->get_my_text().

  WRITE: l_text.

 

  " To do more specific stuff cast go_super to another variable typed

  " to mysub

 

*----------------------------------------------------------------------*

*       CLASS mysuper IMPLEMENTATION

*----------------------------------------------------------------------*

*

*----------------------------------------------------------------------*

CLASS mysuper IMPLEMENTATION.

  METHOD initialise.

    " Can be redefined in subclass to do something more specific

    set_text('I can be super').

  ENDMETHOD.                    "initialise

  METHOD constructor.

    initialise().

  ENDMETHOD.                    "constructor

  METHOD get_my_text.

    re_text = mytext.

  ENDMETHOD.                    "get_my_text

  METHOD set_text.

    mytext = im_text.

  ENDMETHOD.                    "set_text

ENDCLASS.                    "mysuper IMPLEMENTATION

 

*----------------------------------------------------------------------*

*       CLASS mysub IMPLEMENTATION

*----------------------------------------------------------------------*

*

*----------------------------------------------------------------------*

CLASS mysub IMPLEMENTATION.

  METHOD constructor.

    super->constructor().

  ENDMETHOD.                    "constructor

  METHOD createable~create.

    " If you had an import param with type ref to data

    " you could parse it here and raise an exception if invalid

    " but your option of passing a class that implements an interface

    " would also work but you would need to have a public instance attribute

    " available to represent your parameter data

 

    " You can now create an instance of your class

    DATA: lo_obj TYPEREFTO mysub.

 

    " This should call the super class

    " constructor which I thought should invoke the redfined

    " initialise method but it never does.

    " This code works in Java

    CREATEOBJECT lo_obj.

 

    " I can invoke it explicitly here and it works

    "lo_obj->initialise( ).

    re_obj = lo_obj.

 

    " You can set additional subclass specific methods here

    " for functionality that could be handled by the redefined

    " initialise method.  I.e. handle subclass specific import params

 

  ENDMETHOD.                    "creatable~create

  METHOD initialise.

    " Call the super class implementation

    super->initialise().

 

    " Set the text to something more specific

    set_text('I prefer to be sub').

 

    " If necessary you can call additional instance methods to provide additional functionality

    " like re_obj->do_something( ).

  ENDMETHOD.                    "initialise

ENDCLASS.                    "mysub IMPLEMENTATION

 

 

I also created some equivalent code in Java and that works as I expected and the redefined subclass method is called in the constructor.

 

public final class TestFactory {  /**  * @param args  */  public static void main(String[] args) {  // TODO Auto-generated method stub  MySub myObj = MySub.create();  System.out.println(myObj.getText());  }
}

 

abstract class MySuper {  private String myText;  protected MySuper() {      initialise();  }  public String getText(){   return myText;  }  protected void setText(String text){   myText = text;  }  protected void initialise(){   setText("I am Super");  }
}

 

 

public class MySub extends MySuper {  protected MySub() {  super();  }  protected void initialise(){   super.initialise();      setText("I prefer to be sub");  }  public static MySub create(){   return new MySub();  }
}

 

 

Cheers,

 

Katan


Viewing all articles
Browse latest Browse all 8065

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>