Multiple class constructor Matlab - oop

Is it possible define more than one class constructor in Matlab? If yes, how?

Each class has one constructor. However ... the constructor can accept any number and type of arguments, including those based on varargin.
So, to provide the option of a default third argument in Java you could write something like this (examples based on java documentation):
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
public Bicycle(int startCadence, int startSpeed) {
gear = 1;
cadence = startCadence;
speed = startSpeed;
}
In Matlab you could write
classdef Bicycle < handle
properties (Access=public)
gear
cadence
speed
end
methods (Access = public)
function self = Bicycle(varargin)
if nargin>2
self.gear = varargin{3};
else
self.gear = 1;
end
self.cadence = varargin{1};
self.speed = varargin{2};
end
end
end

The answer of Pursuit works, but a user not familiar to the function can't see how many arguments are needed or what they are for. I would recommend this:
methods (Access = public)
function self = Bicycle(startCadence, startSpeed, startGear)
if nargin>2
self.gear = startGear;
else
self.gear = 1;
end
self.cadence = startCadence;
self.speed = startSpeed;
end
end
If you now type "Bicycle(" and wait you can see at least the three arguments. The second possibility is not shown though. It seems possible (e.g. for plot) but I don't know how to do this.

Each class has only one constructor, and each .m-file can only contain one class definition.
If you want to have a class with slight differences depending on input, you can use properties that define switches that are recognized by the class methods. If you want to have very different classes depending on input, you can create a generateClass-function that will call either one or the other class defined in different files. Of course, if these different classes have lots of common methods and properties, you can create both as subclasses to a common superclass.

No. The constructors in OOP matlab are very restricted compared to other languages. It is not explicitly stated in the documentation AFAIK that you can have multiple constructors, but it refers to the constructor of a class in the singular throughout the documentation.
https://www.mathworks.com/help/matlab/matlab_oop/class-constructor-methods.html

Related

Matlab: Class destructor not called during clear?

In Matlab I have a class
classdef myClass
properties
% some properties here...
end
methods ( Access = 'public' )
function obj = myClass()
% constructor...
end
function obj = delete( obj )
% suppose to be destructor...
fprintf(1, 'delete\n');
end
end % public methods
end
What is the default behavior of Matlab when I clear a variable of type myClass?
For example:
>> m = myClass();
>> clear m
I would expect Matlab to call the destructor of m at this stage, but it seems like it doesn't!!
My questions:
How can I force a call to the destructor when clearing a variable?
Is this default behavior of Matlab's makes any sense? Isn't it more logical to call the destructor when clearing a variable?
Is it possible that Matlab's classes do not have a detructor method (that is, there is no default method to be called when the class is destroyed)? Or am I missing something?
Is it possible that only classes derived from handle have a destructor (the delete method)?
Thanks!
EDIT : following Jonas' answer, a brief summary:
Matlab has two types of classes: value classes (the default) and handle classes (derived from handle super class). Value classes tends to provide better performance, however, they do not have a destructor functionality.
handle classes do have a destructor function: delete that is called when the class is destroyed. See this question from more details on handle class destructors.
If one wishes to have a destructor-like functionality for value classes, Jona's answer proposes a method utilizing onCleanup functionality.
Thanks for the good answer and the insightful comments!
Delete is only defined as class destructor for handle classes, not value classes (so the answer to Q4 is "yes", see the previous link to the documentation). Value classes work very much like standard Matlab arrays, in that they're passed by value rather than by reference, and in that many of the internals, such as destructors, are hidden from the user. In exchange, they're usually faster (see for example this SO question).
Consequently, I suggest to use the onCleanup functionality if you want to have a delete method being called (note that delete(m) will not actually delete anything, so you may want to make that a private method).
classdef myTestClass
properties
% some properties here...
end
properties (Hidden)
cleanup
end
methods ( Access = 'public' )
function obj = myTestClass()
% constructor...
obj.cleanup = onCleanup(#()delete(obj));
end
end
methods ( Access = 'private' )
%# I suggest hiding the delete method, since it does not
%# actually delete anything
function obj = delete( obj )
fprintf(1, 'delete\n');
end
end % public methods
end

MATLAB - obtain the object a property belongs to?

Suppose I have a myClass < handle with property A. If I create an instance of myClass, say myObj, and pass myObj.A to a function, say function myFunc(val), is it possible within myFunc to see that the val passed to it is a property of myObj?
EDIT: For context:
I'm writing an API (in a sense) to interface with Arduino hardware for my research lab. The overarching class is called Vehicle, with properties PinManager < handle, TelemCollector < handle, and various Device < handles. It also has methods to do things like runMotor(), getAltitude(), etc. I have a method TelemCollector.telemFetch() which is the callback for a timer event; I would like TelemCollector.telemFetch() to be able to access Vehicle methods (namely getAltitude()); naively I would just make Vehicle a property of TelemCollector to access those methods. I was hoping to not have to do this.
EDIT2: Sample code snippet of what I'm trying to accomplish:
classdef Vehicle < handle
properties
PinManager
TelemCollector
Devices
end
methods
function obj = Vehicle(PM, TC, D)
obj.TC = TelemCollector();
obj.PM = PinManager();
obj.Devices = D();
end
function val = getAltitude(obj)
%# read altitude from a connected Device
end
function val = getSpeed(obj)
%# read speed from connected Device
end
end
end
classdef TelemCollector < handle
properties
%# ...
end
methods
function fetchTelem(obj)
%# do getAltitude(), getSpeed(), etc, here.. but I want to access
%# Vehicle.getAltitude() and Vehicle.getSpeed() somehow!
end
end
end
For all I know, no.
For example if myObj.A is a double, myFunc will just be passed the value it contains and there will be no reference to the object. If you were calling myFunc(somevariable) where somevariable was really the name of a variable and not an expression, then calling inputname(1) inside of myFunc would give you the string 'somevariable', but since you are referring to a property of a class, this is too complicated for MATLAB and inputname(1) just returns '' (tested with MATLAB R2011a).
Update: Why do you need to know this anyhow? If your interfaces are cleanly designed, you should probably not have to do this kind of thing. Or are you trying to work around someone else's bug/bad design? Depending on your application you could think of some kind of very dirty hack involving dbstack, trying to find out which m-file called your function, read the appropriate line of code from the .m file, parse it and then access the object using evalin('caller',...) ... but I doubt that's a good idea ;-).
Edit in response to context you provided:
Can't you just redefine your Timer callback to hand over the "Vehicle" object as well? i.e.
set(yourtimer_handle,'TimerFcn',{#fetchTelem,vehicle_handle});
means that whenever the callback timer calls the function TelemCollector.fetchTelem(), it hands over vehicle_handle as a third argument as described in the docu. This works in conjunction with a changed function head
function fetchTelem(obj, event, vehicle_handle)
where you can replace event by ~ in newer MATLAB versions if you don't need it.
Could that work?
fetchTelem can't call methods of an object that it doesn't have a reference to. So, regardless, you need to provide your TelemCollector object with the Vehicle handle.
Personally, I think the association between Vehicle and TelemCollector should be in the opposite direction. I would prefer something that looked more like:
V = Vehicle(PM, D);
TC = TelemCollector(V);
Although it really depends on how you expect to use the classes.
I agree with #Jonas Heidelberg: if it's this difficult, then it's probably the wrong interface.

What are the best practices for determining the tasks of Constructor, Initialization and Reset methods

This is a general OOP question although I am designing in Java. I'm not trying to solve a particular problem, just to think through some design principles.
From my experience I have reached the habit segregating object setup into three phases.
The goal is to minimize: extra work, obfuscated code and crippled extensibility.
Construction
The minimal actions necessary to
create a valid Object, passes an
existence test
Instantiate and initialize only "one time", never to be over-ridden, non variable objects that will not change/vary for the life of the Object
Initialize final members
Essentially a runtime stub
Initialization
Make the Object useful
Instantiate and initialize publicly accessible members
Instantiate and initialize private members that are variable values
Object should now pass external tests with out generating exceptions (assuming code is correct)
Reset
Does not instantiate anything
Assigns default values to all variable public/private members
returns the Object to an exact state
A Toy example:
public class TestObject {
private int priv_a;
private final int priv_b;
private static int priv_c;
private static final int priv_d = 4;
private Integer priv_aI;
private final Integer priv_bI;
private static Integer priv_cI;
private static final Integer priv_dI = 4;
public int pub_a;
public final int pub_b;
public static int pub_c;
public static final int pub_d = 4;
public Integer pub_aI;
public final Integer pub_bI;
public static Integer pub_cI;
public static final Integer pub_dI = 4;
TestObject(){
priv_b = 2;
priv_bI = new Integer(2);
pub_b = 2;
pub_bI = new Integer(2);
}
public void init() {
priv_a = 1;
priv_c = 3;
priv_aI = new Integer(1);
priv_cI = new Integer(3);
pub_a = 1;
pub_c = 3;
pub_aI = new Integer(1);
pub_cI = new Integer(3);
}
public void reset() {
priv_a = 1;
priv_c = 3;
priv_aI = 1;
priv_cI = 3;
pub_a = 1;
pub_c = 3;
pub_aI = 1;
pub_cI = 3;
}
}
I would design my classes in a way so that an "init" method is not required. I think that all methods of a class, and especially public methods, should guarantee that the object is always left in a "valid" state after they complete successfully and no call to other methods is required.
The same holds for constructors. When an object is created, it should be considered initialized and ready to be used (this is what constructors are for and there are numerous tricks to achieve this). Otherwise, the only way that you can safely use it is checking if the object has been initialized in the beginning of every other public method.
I come from a C++ background where the rules are a bit different from Java, but I think these two-stage initialization principles apply in the general case.
Construction
Everything that can be done at construction time should be done at construction time.
Minimize the amount of "badness" that can result from trying to use your object before calling init().
All member variables need a value, even if it's a normally invalid sentry value (e.g., set pointers to null). I think Java will initialize all variables to zero by default, so you need to pick something else if that's a valid number.
Initialization
Initialize those member variables that depend on the existence of other objects. Basically, do the things you couldn't do at construction time.
Ensure your object is now in a complete, ready-to-use state. Consider throwing an exception if it isn't.
Reset
Think long and hard about what state The System will be in when you'd want to call such a function. It may be better to create a new object from scratch, even if that operation seems expensive. Profile your code to find out if that's a problem.
Assuming you got past item 1, consider writing a method to handle the things that both reset() and your constructor need to do. This eases maintenance and avoids code duplication.
Return your object to the same state it was in after init().
Can't say that I've ever used this exact pattern, but I've used similar things to reduce code duplication. For example when you have an object that may be either created via a constructor or from a another object (like a DTO) via a factory method. In that case, I'll often have an internal initializer that populates the properties of the object that is used by both. Can't say that I've ever used a "reset" method, nor do I see a real need for one if all it does is replicate the process of creating a new object.
Lately, I've moved to only using default constructors and using property settors to initialize the object. The new C# syntax that allows to easily do this in a "constructor-like" format makes this every easy to use and I find the need to support parameterized constructors disappearing.
Is there a reason init() and reset() need to be different? It's hard to see in this simple example why the "does not instantiate anything" rule is important.
Beyond that, I think objects should be useful as soon as they're constructed. If there's a reason -- some circular dependency or inheritance issue -- an object has to be "initialized" after construction, I would hide the constructor and the initialization behind a static factory method. (And probably move the initialization code to a separate configurator object for good measure.)
Otherwise you're counting on callers always to call both the constructor and init(), and that's a non-standard pattern. We have some old, too-useful-to-throw-away code here that does that; it's an abstract dialog class, and what happens is, every time someone extends it, they forget to call constructUI() and then they waste 15 minutes wondering why their new dialog is empty.
Interesting. I especially find this construction useful if you have an object that needs to perform IO operations. I do not want anything to perform IO operations direct or indirectly in their constructor. It makes the object a nightmare to use.

Matlab subclassing question

Question about subclassing in matlab, under the new class system. I've got class A with some protected properties:
classdef Table < Base
properties (SetAccess = protected, GetAccess = public)
PropA = [];
end %properties
I'd like to make a subclass with some specialized features, and further restrict access to PropA. (i.e. make get access private in the subclass). My first thought was:
classdef subTable < Table
...
methods (Access = private)
out = get.PropA(obj, value);
end %private methods
However, in the help it says: "You must define property access methods in a methods block that specifies no attributes." So much for that idea.
Any ideas?
I don't believe this is possible. From MATLAB Documentation:
There are only two conditions that allow you to redefine superclass properties:
The superclass property Abstract attribute is set to true
The superclass property has both the SetAccess and GetAccess attributes set to private
Nor do I think that doing this would be a good idea. It violates the Liskov Substitution Principle. Functions written to accept a Table should also be able to accept a subTable and work properly. If such a function accessed PropA, it would fail when passed a subTable.

Best Practice: Abstract data via get/set or allow access to the variable?

I was writing some python classes the other day, and created a class like this:
class Option:
Name = ""
Description = ""
Criteria = {}
def __init__(self, name, descr):
self.Name = name
self.Description = descr
def addCriteria(self, cname, ctype):
...
In my program, I was accessing the data in the class directly, i.e.:
cname = opt.Name
While this was a conscious decision, I know a lot of classes would have abstracted this as:
cname = opt.getName()
Should I have taken the time to abstract all the data and not allow direct access? What triggers when you would add access methods for class data?
Mike
Even though this goes against anything you learn when doing OOP, I would suggest, that you defer the decision until it really turns out, that you need some "magic" to take place on attribut access. In Python, it is easy enough to refactor the class providing the attributes using the special property function:
class ItsMagic(object):
_name = None
def _get_name(self):
return self._name
def _set_name(self, new_name):
self._name = new_name
Name = property(_get_name, _set_name)
magic = ItsMagic()
magic.Name = "Foo"
This is transparent to the clients of this class, ie., they cannot usually tell (and should not care), whether the property reference is handled by providing access to the actual object attribute or by means of magic getter/setter functions, and it can be applied later (if it turns out to be required, that is).