Question: how to extend class (module of type object) in Maple? Problem calling base class constructor

In traditional OOP, one can have a base class with its own constructor. Then extends this class, where the sub class has also its own consturctor. The first thing one does in the extending class constructor is to initialize the base class by calling base class constructor directly, before finishing the initializing of the extending class.

This is done in different ways. in Java the call super(...) is used for example. in C++ it is done by explicit call to base class constructor. Here is an example.  from the net.

But in Maple, I am not able to duplicate this. Because once ModuleCopy is defined (which is the name for the module constructor) in the base class, I can't have another ModuleCopy in the extending/child class. Maple complains because the name already exists.

In the following example, the base class represents a generic ode.

Then the extending/child class is meant to represent a first order ode which extends the base class and adds some specific functions that only meant to apply for first order ode type.

Later on I want to make a second order ode class and so on. All extend the base ode class. 

My question is: How to extend a class in Maple and have the extending/child class constructor call the base class constructor if one can't have more than one constructor when extending?

This Maple help shows one example of inhertance using Objects but this example does not use a constructor in the base of the child. I am assuming one needs to use ModuleCopy as the name for the constuctor since it specifies how an object is copied by Object so can't make my own function and pretend it is the constructor.

restart;

interface(version)

`Standard Worksheet Interface, Maple 2023.0, Windows 10, March 6 2023 Build ID 1689885`

ode_class:=module()
   option object;
   local ode::`=`;
   local x::symbol;
   local y::symbol;

   #constructor
   export ModuleCopy::static := proc( _self::ode_class, proto::ode_class, ode, func, $ )
    _self:-ode:= ode;
    _self:-y:=op(0,func);
    _self:-x:=op(1,func);
   end proc;

   export get_ode::static:=proc(_self,$)
     return _self:-ode;
   end proc;

   export get_x::static:=proc(_self,$)
     return _self:-x;
   end proc;

   export get_y::static:=proc(_self,$)
     return _self:-y;
   end proc;


end module;

_m2586207352192

first_order_ode_class:=module()
   option object(ode_class);
   local is_linear_ode::truefalse;

   #constructor
   export ModuleCopy::static := proc( _self::first_order_ode_class, proto::first_order_ode_class, ode, func, $ )
    #How to call base class above constructor here?

    _self:-is_linear_ode:= false;
   end proc;

   export is_linear::static:=proc(_self,$)
          return _self:-is_linear_ode;
   end proc;
          
end module;

Error, (in first_order_ode_class) export `ModuleCopy` is declared more than once

ode:=Object(first_order_ode_class,diff(y(x),x)=sin(x),y(x));

_m2586207319808

ode:-get_ode();
ode:-is_linear()

false

 


Download base_class_constructor.mw

UPDATE

This is workaround which seems to work OK. do not use ModuleCopy to construct an object, but have custom named function for each base and each child and call these explicitly.

So child constructor will  now call its parent constuctor using the specific name of that function. May be using some convention as  module_name_constuctor(....)   passing it what the parents needs.

The drawback is that now copying an object does not work automatically since ModuleCopy is missing.  but so far, I never had the need to copy one object to another, so I can live without it for now.
 

1421372

restart;

1421372

ode_class:=module()
   option object;
   local ode::`=`;
   local x::symbol;
   local y::symbol;

   #constructor
   export ode_constructor::static := proc( _self,ode::`=`, func, $ )
     print("inside ode_class constrructor");
    _self:-ode:= ode;
    _self:-y:=op(0,func);
    _self:-x:=op(1,func);
    NULL;
   end proc;

   export get_ode::static:=proc(_self,$)
     return _self:-ode;
   end proc;

   export get_x::static:=proc(_self,$)
     return _self:-x;
   end proc;

   export get_y::static:=proc(_self,$)
     return _self:-y;
   end proc;

end module;

_m2325067887904

first_order_ode_class:=module()
   option object(ode_class);
   local is_linear_ode::truefalse;

   #constructor
   export first_order_ode_constructor::static := proc( _self,ode::`=`, func, $ )
      print("inside first_order_ode_class constrructor");
      #call base class constructor
      _self:-ode_constructor(ode,func);
      #finish rest of constructor  
     _self:-is_linear_ode:= false;
     NULL;
   end proc;

   export is_linear::static:=proc(_self,$)
          return _self:-is_linear_ode;
   end proc:
          
end module;

_m2325067872672

o:=Object(first_order_ode_class);
o:-first_order_ode_constructor(diff(y(x),x)=1,y(x));

_m2325067860896

"inside first_order_ode_class constrructor"

"inside ode_class constrructor"

o:-get_ode()

diff(y(x), x) = 1

o:-is_linear()

false

 


I think Maple OOP is not fully OOP,  but it is better than nothing.

Download base_class_no_constructor.mw

 

Please Wait...