changing class properties with its methods - matlab

I'd like to change my class properties with a method defined for that class:
classdef triangle<handle
properties
a
h
end
methods
function obj = triangle()
obj;
end
function obj = setProps(obj, a, h)
obj.a = a;
obj.a = h;
end
end
end
Calling:
t = triangle();
t.setProps(a, h);
It's not working at all - I get this error:
The class 'handle' is not a super-class of class 'triangle', as required to invoke a super-class constructor or method.
Error in triangle (line 13)
function obj = triangle()
I'm using matlab 2012a. My code is based on this example: link

Try clear before doing this. It is possible that you've overwritten handle with something. Otherwise, this works for me on Matlab 2012a:
clear;
a = 'hello';
h = 1;
t = triangle();
t.setProps(a, h);

Related

In matlab, I got different values in a method of class and out

In the matlab, I defined a class and instantiated the class in another script, but I got different values in and out of the method. My matlab code are shown bellow:
test_add.m
classdef test_add
properties
a
b
end
methods
function obj = test_add(a, b)
obj.a = a;
obj.b = b;
end
function c = add_1(obj)
c = obj.a + 1;
end
function inter(obj, t)
for i = 1:t
obj.a = obj.add_1();
end
fprintf('In the method:\n');
fprintf('a = %d\n',obj.a);
fprintf('b = %d\n',obj.b);
disp('=======================');
end
end
end
main.m
tt = test_add(1,2);
tt.inter(3);
fprintf('Out of the method:\n');
fprintf('a = %d\n',tt.a);
fprintf('b = %d\n',tt.b);
output:
In the method:
a = 4
b = 2
=======================
Out of the method:
a = 1
b = 2
In Matlab there are two type of classes: handle class and Value class. If you said nothing you get the Value class. Most of the OO languages out there are using handle class semantic.
So, you have two options:
Change you class to handle class by inheriting from handle
classdef test_add < handle
Stay with Value class and change your inter function to return obj.
But then, in main call obj=tt.inter(3) to get the updated object.
function obj = inter(obj, t)
for i = 1:t
obj.a = obj.add_1();
end
fprintf('In the method:\n');
fprintf('a = %d\n',obj.a);
fprintf('b = %d\n',obj.b);
disp('=======================');
end
It's a problem of value class vs handle class, the solution is:
test_add.m
classdef test_add < handle
...
end
Then, the output is:
In the method:
a = 4
b = 2
=======================
Out of the method:
a = 4
b = 2

Attaching function to Matlab struct

Is it possible to attach a function to a class property of type struct? Intended usage:
% Definition:
classdef a < handle
properties
bar
end
methods
function obj = a()
obj.bar = struct;
%obj.bar.attachFunction('apply', #someFunction); <-- something like this
end
end
end
% Usage:
foo = a();
foo.bar.apply('test');
foo.bar.var1 = 1;
foo.bar.var2 = 2;
Oh well, that was actually quite simply once I used my mind.
classdef a < handle
properties
bar
end
methods
function obj = a()
obj.bar = struct;
obj.bar.apply = #(str) #obj.barApply(str);
end
end
methods (Access=protected)
function barApply(obj, str)
obj.bar.something = str;
end
end
end
foo = a();
foo.bar.apply('monkey');
foo.bar.apple = 2;

How to make an object accessible within its class, in Matlab?

In this class how can I have fig object with its own relevant properties available in its class, for example in my_function;
classdef Test
properties
a
b
end
methods
function obj = Test(a, b)
obj.a = a;
obj.b = b;
end
function [] = my_function(obj)
fig.Name %%% here fig object is needed
disp('done!')
end
function [fig] = my_figure(obj)
fig = figure();
end
end
end
You need to store fig as a property of your class and then from within my_function, you'll be able to access the fig property of the current instance. As a side note, if you'd like to be able to pass your class instance around by reference, you'll want to subclass MATLAB's handle class:
classdef Test < handle
properties
fig % Setup a property to hold the handle to the figure
a
b
end
methods
function obj = Test(a, b)
obj.a = a;
obj.b = b;
end
function [] = my_function(obj)
% Access and modify the figure handle as needed
obj.fig.Name = 'Name';
disp('done!')
end
function [fig] = my_figure(obj)
fig = figure();
% Store the handle in the "fig" property of the class
obj.fig = fig;
end
end
end

What does this MATLAB class to and why isn't it working on my PC?

The very first one in this documentation:
http://www.mathworks.com/help/matlab/matlab_oop/getting-familiar-with-classes.html
The class is:
classdef BasicClass
properties
Value
end
methods
function r = roundOff(obj)
r = round([obj.Value],2);
end
function r = multiplyBy(obj,n)
r = [obj.Value] * n;
end
end
end
When I run it this way
a = BasicClass
a.Value = pi/3;
It works fine and does what it should but this piece of code
a = BasicClass(pi/3);
Gives the following error:
"Error using round
Too many input arguments."
What does it mean? (I'm using R2014a) Is it stupid to use oop in Matlab? LOL
Your error message doesn't look correct compared with the code, whichever your missing a class constructor (as is mentioned at the half way down the help link):
classdef BasicClass
properties
Value
end
methods
% Class constructor -> which you can pass pi/3 into.
function obj = BasicClass ( varargin )
if nargin == 1
obj.Value = varargin{1};
end
end
% Your Methods
function r = roundOff(obj)
r = round([obj.Value],2);
end
function r = multiplyBy(obj,n)
r = [obj.Value] * n;
end
end
end

Initialize child before parent - do not call parent contructor

In MatLab, i have a superclass A that takes some parameters, x and y
classdef A < handle
properties
x;
y;
z;
end
methods
function this = A(x, y)
this.x = x;
this.y = y;
this.initialize();
end
function initialize(this)
this.z = this.x + this.y;
end
end
end
The initialize method is supposed to do some initial calculations to fasten computation later.
Now i want to create a child class B of A, with it's own inialization, but B should be initialized before A.
classdef B < A
properties
p
end
methods
% B takes another parameter p
function this = B(p)
% Since B is a subclass of A, and A takes some parameters we have to
% call the constructer of A as the first thing.
this = this#A([], []);
this.p = p;
end
function initialize(this)
this.x = this.p(1);
this.y = this.p(2);
% This is when initialize of A should be called.
end
end
end
Basically i just want to initialize B before A, but because the constructer of the parent have to be called as the first thing, i cannot figure out how to do this.
In PHP I would do something like this
class A {
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
$this->initialize();
}
public function initialize() {
$this->z = $this->x + $this->y;
}
}
class B extends A {
public function __construct($p) {
// Does not call the parent constructor.
$this->p = $p;
$this->initialize();
}
public function initialize() {
$this->x = $this->p[0];
$this->y = $this->p[1];
parent::initialize(); // Now we are ready to initialize A
}
}
Is there a smart way to design what i want in MatLab? Do i have to give up the inheritance of A in class B?
The complication arises since:
If you create a subclass object, MATLABĀ® calls the superclass constructor to initialize the superclass part of the subclass object. By default, MATLAB calls the superclass constructor without arguments. [src]
You can get around explicitly calling the superclass constructor by wrapping its work in an if-statement dependent on how many arguments it was passed (nargin):
function this = A(x, y)
if (nargin ~= 0) % or (nargin == 2) in this case
this.x = x;
this.y = y;
this.initialize();
end
end
And then B's methods would look like:
function this = B(p)
this.p = p;
this.initialize();
end
function initialize(this)
this.x = this.p(1);
this.y = this.p(2);
initialize#A(this);
end
It may just be error in the post, but A's initialize method is referencing undefined variables x and y and not their properties. It should be:
function initialize(this)
this.z = this.x + this.y;
end
This goes against the principles of OOP. What you are trying to achieve basically rules out that B should be derived from A. From what I can tell, you really want to overload the constructor of A. Either do this using a nargin check in A, or if you really want to have a B for whatever reason, just use: this = this#A(p(1), p(2); in the constructor of B instead, to properly call the constructor of A (and get rid of the property p).
This is how you would simulate to overload the constructor by using nargin:
classdef A < handle
properties
x;
y;
z;
end
methods
function this = A(x, y)
if nargin==1 % 'p' was passed as 'x'
this.x = x(1);
this.y = x(2);
else
this.x = x;
this.y = y;
end
this.initialize();
end
function initialize(this)
this.z = this.x + this.y;
end
end
end
This is how you would derive B from A, with a proper call of A's constructor:
classdef B < A
methods
function this = B(p)
this = this#A(p(1), p(2));
end
end
end