How to use private methods inside public methods in matlab - matlab

I have couple methods in Matlab class. I am accessing few of them in some of these methods but somehow, in order to call those methods, I need to place "instaceName." in start of method names. I have c# background and does not feel comfortable. In C#, different level of visibility of methods can be defined.
classdef SampleClass
%UNTITLED2 Summary of this class goes here
% Detailed explanation goes here
properties
result ;
end
methods
function method1 (obj, a , b)
obj.result = obj.method2 (a,b) ;
end
end
methods (Access= private)
function y = method3 ( a , b)
y = a + b ;
end
end
end
If I define methods as static which I want to use internally in that class then will it work.
Is there a suggestion to deal this issue.
classdef SampleClass
%UNTITLED2 Summary of this class goes here
% Detailed explanation goes here
properties
result ;
end
methods
function method1 (obj, a , b)
obj.result = SampleClass.method2 (a,b) ;
end
end
methods (Static)
function y = method2 ( a , b)
y = a + b ;
end
end
end

Unfortunately there is no workaround for the issue that you mention. Class method signatures must always pass the "instance" into itself:
function output = DoSomething(this, arg1, arg2)
There are several methods to call a class method (take for example the above method DoSomething from Class MyClass):
my_instance = MyClass(...);
% Call type 1
output = my_instance.DoSomething(arg1, arg2)
% Call type 2
output = DoSomething(my_instance, arg1, arg2)
The type 2 feels more intuitive and aligned with the function signature.
In your example, both the instance method and the static method are interchangeable because you are not using method properties. But that's not always the case: static methods cannot access the private/protected properties of the class.
Extra note: as far as I know, many OO languages do the same but behind the scenes (C++ and C# automatically add the instance argument to the method, but correct me if I am wrong). The only difference is that in Matlab you must do it explicitly.
C++ explanation.

Related

Program in same OOP style as App Designer

I like the OO programming style that matlabs App Designer uses (or at least the way I'm using it). Now I'm wondering if I can use the same style in my "normal" matlab class.
What I have now:
classdef myClass
properties
myVar;
end
methods
function Main(obj)
obj.myVar = "a";
obj = DoSomething(obj);
disp(obj.myVar) % outputs "c"
end
function obj = DoSomething(obj)
if(obj.myVar == "a")
obj.myVar="c";
else
obj.myVar = "b";
end
end
end
end
Which can be called externally using:
myClassInst = myClass;
myClassInst.Main()
I would like to get rid of all the "obj = " in the classdef, as is possible in App Designer. So something that would look like this:
classdef myClass
properties
myVar;
end
methods
function Main(obj)
obj.myVar = "a";
DoSomething(obj); % Just call the function without "obj = "
disp(obj.myVar) % outputs "a" because I didn't overwrite obj
end
function DoSomething(obj)
if(obj.myVar == "a")
obj.myVar="c";
else
obj.myVar = "b";
end
end
end
end
The equivalent of this seems to work in App Designer. So it appears you can modify variables in a class (instance?) in App Designer, while also being able to access the modified variable without explicitly overwriting your old class instance.
I noticed App Designer has all methods an properties set to (Access = private), though I'm not sure that has anything to do with it. Of course if I set everything to private, then I can't access the Main() method from outside anymore.
So my question is, how can I program in "normal" matlab, the same way as is possible in App Designer?
EDIT:
The following works in App Designer (I left out the methods/properties for the GUI elements):
classdef tmp < matlab.apps.AppBase
properties (Access = private)
myVar; % Description
end
methods (Access = private)
function doSomething(app)
if app.myVar == "a"
app.myVar = "c";
else
app.myVar = "b";
end
end
end
% Callbacks that handle component events
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
app.myVar = "a";
doSomething(app);
disp(app.myVar); % outputs "c"
end
end
end
You definitely can! All you have to do is inherit from the handle class, as opposed to a value class which is the default for matlab. You can also define private and public methods as in other languages.
The only thing you have to do is:
classdef myclass < handle % this is how you inherit from base class
properties
public_property
end
properties (Access=private)
private_property
end
methods
function obj = myclass() % class constructor
...
end
function public_function()
...
end
end
methods (Access=private)
function private_function()
...
end
end
end
Now every time you pass an object of this class to a function, you are not passing it by value, you are passing by reference (as you might be used to from python) and modifying it's properties modifies them also in the original object.
You need to inherit (< at the top of the class) from a handle class
classdef myClass < handle
properties
var
end
methods
function obj = myClass( varargin )
% Constructor function, called automatically when object is created
end
function someFunction( obj )
obj.randomizeVar(); % Equivalent to randomizeVar( obj );
end
function randomizeVar( obj )
obj.var = rand();
end
end
end
See the documentation for the difference between a "handle" and "value" class:
A value class constructor returns an object that is associated with the variable to which it is assigned. If you reassign this variable, MATLABĀ® creates an independent copy of the original object. If you pass this variable to a function to modify it, the function must return the modified object as an output argument. For information on value-class behavior, see Avoid Unnecessary Copies of Data.
A handle class constructor returns a handle object that is a reference to the object created. You can assign the handle object to multiple variables or pass it to functions without causing MATLAB to make a copy of the original object. A function that modifies a handle object passed as an input argument does not need to return the object.
Moreover, if you edit matlab.apps.AppBase, the class which you app designer code inherits, you can see that the first line is
classdef AppBase < handle
So you are literally doing the same thing, without the AppBase middle-man.

Private constructor in matlab oop

Matlab does not allow to define different methods to define multiple constructors with different list of parameters, for instance this will not work:
classdef MyClass
methods
function [this] = MyClass()
% public constructor
...
end
end
methods (Access = private)
function [this] = MyClass(i)
% private constructor
...
end
end
end
But, as illustrated in above example, it is sometimes useful to have private constructors with particular syntax that cannot be called from public interface.
How would you best handle this situation where you need to define both public and private constructors ?
Checking call stack ???
classdef MyClass
methods
function [this] = MyClass(i)
if (nargin == 0)
% public constructor
...
else
% private constructor
checkCalledFromMyClass();
...
end
end
end
methods(Static=true, Access=Private)
function [] = checkCalledFromMyClass()
... here throw an error if the call stack does not contain reference to `MyClass` methods ...
end
end
end
Define a helper base class ???
% Helper class
classdef MyClassBase
methods (Access = ?MyClass)
function MyClassBase(i)
end
end
end
% Real class
classdef MyClass < MyClassBase
methods
function [this] = MyClass()
this = this#MyClassBase();
end
end
methods (Static)
function [obj] = BuildSpecial()
obj = MyClassBase(42); %%% NB: Here returned object is not of the correct type :( ...
end
end
end
Other solution ???
One sneaky trick that I've used to try and work around this limitation is to use another 'tag' class that can only be constructed by MyClass, and then use that to work out which constructor variant you need. Here's a simple sketch:
classdef MyClass
properties
Info
end
methods
function o = MyClass(varargin)
if nargin == 2 && ...
isa(varargin{1}, 'MyTag') && ...
isnumeric(varargin{2}) && ...
isscalar(varargin{2})
o.Info = sprintf('Private constructor tag: %d', varargin{2});
else
o.Info = sprintf('Public constructor with %d args.', nargin);
end
end
end
methods (Static)
function o = build()
% Call the 'private' constructor
o = MyClass(MyTag(), 3);
end
end
end
And
classdef MyTag
methods (Access = ?MyClass)
function o = MyTag()
end
end
end
Note the Access = ?MyClass specifier which means that only MyClass can build instances of MyTag. There's more about using that sort of method attribute in the doc: http://www.mathworks.com/help/matlab/matlab_oop/method-attributes.html
You can have a constructor that accepts multiple syntaxes by taking advantage of varargin:
classdef MyClass
methods (Access = public)
function obj = MyClass(varargin)
% Do whatever you want with varargin
end
end
end
You might, more typically, have some inputs that are required for all syntaxes, and then some optional inputs as well:
classdef MyClass
methods (Access = public)
function obj = MyClass(reqInput1, reqInput2, varargin)
% Do whatever you want with varargin
end
end
end
If you want to have even more control over how things are constructed, I would have a constructor and then also have some public static methods that called the constructor.
For example, let's say I wanted to be able to construct an object either by supplying parameters directly, or by supplying the name of a config file containing parameters:
classdef MyClass
methods (Access = public)
function obj = MyClass(reqInput1, reqInput2, varargin)
% Do whatever you want with varargin
end
end
methods (Static, Access = public)
function obj = fromFile(filename)
myparams = readmyconfigfile(filename);
obj = MyClass(myparams.reqInput1, myparams.reqInput2, ...);
end
end
end
Then you can create an object either with o = MyClass(inputs) or o = MyClass.fromFile(filename).
If you wanted to allow people to construct only from a config file, you could then make the constructor private. And you could add additional public static methods if you wanted to call the constructor in other ways.
In any case, the main point is that the idiomatic way to have a constructor that accepts multiple syntaxes is to take advantage of varargin.
I'd be tempted to go for a modification on your 1st option, but to modify the constructor to have an undocumented "mode" rather than just any input arg.
In the example below I gave that name **private** but you could have anything you want that the end users are unlikely to stumble across....
To be doubly sure you could still check the stack.
function [this] = MyClass(i)
if (nargin == 0)
% public constructor
else
% private constructor
if ischar ( i ) && strcmp ( i, '**private**' )
this.checkCalledFromMyClass();
else
error ( 'MyClass:Consturctor', 'Error calling MyClass' );
end
end
end
end

Calling class object from a function without insert it to the function in MATLAB

We have this code in 'Reconstruction the subclass object from a saved struct' from MATLAB OOP documentation.
classdef MySuper
% Superclass definition
properties
X
Y
end
methods
function S = saveobj(obj)
% Save property values in struct
% Return struct for save function to write to MAT-file
S.PointX = obj.X;
S.PointY = obj.Y;
end
function obj = reload(obj,S)
% Method used to assign values from struct to properties
% Called by loadobj and subclass
obj.X = S.PointX;
obj.Y = S.PointY;
end
end
methods (Static)
function obj = loadobj(S)
% Constructs a MySuper object
% loadobj used when a superclass object is saved directly
% Calls reload to assign property values retrived from struct
% loadobj must be Static so it can be called without object
obj = MySuper;
obj = reload(obj,S);
end
end
end
I have a question about obj = MySuper. What is purpose of this line? How we can call MySuper object from this function without insert any object to loadobj function?
You first question is: What is the purpose of the obj = MySuper; line?
The answer is that the obj = MySuper; line initiates the variable obj as an element of the class MySuper. Non-static functions in a class will only run if the first input parameter is an instance of the class, so if obj is not initiated as a MySuper-object, then matlab will look for other functions called reload to run, and if none is found give you an error.
For your second question, I am not 100% sure what you mean. But I hope one of the following points will answer your question:
If you want to make a function that relates to a class, but not to a specific instance of the class, you can make a static function, these can take any input (also (if you want it that way) no input at all) - that is they don't need to have a first input parameter of the specific class.
To run a static function, use the class name followed by a dot and then the function name, so here you would type MySuper.loadobj(S) to run the function with the parameter S.
I would suggest that you try this out with the given example to better get to know the way oop works in matlab, you may for example try:
S.PointX = 1;
S.PointY = 2;
obj = MySuper.loadobj(S)
I hope this answers your questions.

MATLAB CLASSES getter and setters

I come from a Java background. I am having issues with classes in Matlab particularly getters and setters. getting a message saying conflict between handle and value class I'm a little lost with what to do so any help for lack of a better word will be helpful.
classdef Person
properties(Access = private)
name;
age;
end
methods
% class constructor
function obj = Person(age,name)
obj.age = age;
obj.name = name;
end
%getters
function name = get.name(obj)
end
function age = get.age(obj)
end
%setters
function value = set.name(obj,name)
end
function value = set.age(obj,age)
end
end
end
Implementation
Since your class is currently a subclass of the default Value class, your setters need to return the modified object:
function obj = set.name(obj,name)
end
function obj = set.age(obj,age)
end
From the documention: "If you pass [a value class] to a function, the function must return the modified object." And in particular: "In value classes, methods ... that modify the object must return a modified object to copy over the existing object variable".
Handle classes (classdef Person < handle) do not need to return the modified object (like returning void):
function [] = set.name(obj,name)
end
function [] = set.age(obj,age)
end
Value vs. Handle
Going a bit deeper, the difference between a Value class and a Handle class lies mostly in assignment:
Assigning a Value class instance to a variable creates a copy of that class.
Assigning a Handle class instance to a variable create a reference (alias) to that instance.
The Mathworks has a good rundown on this topic.
To paraphrase their illustration, the behavior of a Value class is
% p is an instance of Polynomial
p = Polynomial();
% p2 is also an instance of Polynomial with p's state at assignment
p2 = p;
and of a Handle class is
% db is an instance of Database
db = Database();
% db2 is a reference to the db instance
db2 = db;
Quick'n Dirty from the Java perspective:
- "handle" classes are what your mind is set to. proper object instances with pointers to them. use them.
- "value" classes are always returning a full clone of whatever object (which has been modified by what you just did, e.g. setting a name).
the reason they have both in Matlab is that in Matlab you would expect the "value" behaviour natively. Imagine you have a matrix A = [1 2; 3 4], then assign that via B = A. if you now set B(1) = -1 you'd hope that A(1) is still 1, right? this is because matlab keeps track of "copies" and truly creates them as you modify different variables initially set to the same matrix. in OOP you'd have A(1)=-1 now as everythings an object reference.
furthermore, "native" matlab routines dont have a "this/self/me" variable that contains the instance reference to access from within functions. instead, the convention is that the class instance will be prepended to the function's argument list.
so for a function call myclass.mymethod(arg1,arg1), the declaration must be
function mymethod(this, arg1, arg2)
% Note that the name you choose for "this" is arbitrary!
end
mind you, this is the java-perspective (and also my favourite one), the above function call is equivalent to mymethod(myclass,arg1,arg1). this is more native to matlab-style, but somehow makes it harder to see you're calling an objects method.
now, regarding setters/getters: for handle classes, everything feels java-ish now:
classdef MyClass < handle
properties
MyProp;
end
methods
function set.MyProp(this, value) %Note: setMyProp is also valid!
... % do checks etc, trigger calls,
this.MyProp = value;
end
function value = get.MyProp(this)
... % notify, update, triggers etc
value = this.MyProp;
end
end
Of course it goes without saying that you dont need to define a getter if you just want to return the value, i.e. myclassinstance.MyProp will work without any just as well.
Finally, getters/setters for value classes are something that [never encountered me/i never needed] in my 7 years of matlab oop, so my advise would be to go with handle classes and enjoy happy matlab coding :-)
otherwise, the above explanation & official matlab docs is doing the job for value class getter/setters.

How to cancel a superclasses' overriding of a default Matlab function

I have two classes, a superclass and subclass. The subclass inherits from the superclass.
The superclass redefines the default Matlab function disp(). However, I want the subclass to "cancel" this redefinition and go back to using the default Matlab version of disp(). Is there any way to do this?
I know that subclasses can call superclasses' methods via the following syntax
function result = CallTheSuperClassMethod(obj, arg1, arg2)
result = TheSuperClassMethod#TheSuperClass(obj, arg1, arg2)
end
But is there a way to call the Matlab default method via something like:
function result = CallTheDefaultMethod(obj, arg1, arg2)
result = SomeMethod#DefaultClass(obj, arg1, arg2)
end
where I am assuming that DefaultClass is the class from which all Matlab classes inherit.
Here's a concrete example. I have two classes, defined as follows:
classdef blah_super
properties
superprop = 'super property';
end
methods
function disp(obj)
disp('super');
end
end
end
classdef blah_sub < blah_super
properties
subprop = 'sub property';
end
end
Here are the results of a few commands that I get:
>> a = blah_super
a =
super
>> b = blah_sub
b =
super
But I want to modify blah_sub somehow (while still inheriting from blah_super) so the result is:
>> b = blah_sub
b =
blah_sub with properties:
subprop: 'sub property'
superprop: 'super property'
Thanks in advance.
Try using builtin
So the definition of blah_sub would be something like this:
classdef blah_sub < blah_super
properties
subprop = 'sub property';
end
methods
function disp(obj)
builtin('disp', obj);
end
end
end