This is done using overload with different ModuleCopy proc in the class.
Here is an example. Lets make a constructor that takes an ode and initial conditions, and one that only takes an ode with no initial conditions.
restart; module ODE() option object; local ode:=NULL; local y::symbol; local x::symbol; local ic:=NULL; local sol; export ModuleCopy::static:= overload( [ proc( _self::ODE, proto::ODE, ode, func, $ ) option overload; _self:-ode:= ode; _self:-y:=op(0,func); _self:-x:=op(1,func); end proc, proc( _self::ODE, proto::ODE, ode, func, ic, $ ) option overload; _self:-ode:= ode; _self:-y:=op(0,func); _self:-x:=op(1,func); _self:-ic :=ic; end proc ] ); export dsolve::static:=proc(_self,$) if evalb(ic=NULL) then sol := :-dsolve(ode,y(x)); else sol := :-dsolve([ode,ic],y(x)); fi; end proc; export get_sol::static:=proc(_self,$) return sol; end proc; end module;
And now use it as follows