I have the following problem. I have three classes: A, B, and C. A is the base class, B inherits A, and C inherits B.
Each has a constructor that takes in alot of arguments. However, the constructor for B does a few steps that I don't want in C that I can't undo unless I add more interface code, which would break encapsulation for a few variables. Namely, I'd give the user of my class the ability to change a few variables that I don't want them to.
As a result, I thought that I'd be clever and try to call the constructor of A from C. However MATLAB doesn't like this. See code below.
classdef C < B
% properties go here
% ...
methods(Access = public)
function obj = C(arguments)
obj = obj#A(A's arguments); % MATLAB doesn't like this
% ...
end
end
So, how can I (or can I not), call the constructor to A?
the constructor for B does a few steps that I don't want in C
In that case, your C is not an B. If the constructor from B is not executed in the construction process of C, then C cannot be a valid object of class B. However, the inheritance relationship implies this.
As such, the inheritance C < B is wrong. You should inherit C from A.
If you really want to, I'd try to implement a (mostly empty) protected constructor in B that is then called from C. Not entirely sure that works in Matlab though.
Related
I tried to change an attribute value of a class by invoking one of its member function:
p1 = tank();
p1.checkOri(p1);
And in the class definition, I have that static method:
classdef tank
properties
value
...
end
methods
...
methods (Static)
function obj = checkOri(obj)
if (CONDITION) %the thing I want it to do
obj.value = EXPRESSION;
...
Yet this checkOri method is not working. But if I write this method in the main file, or to say altering the value of p1-the instance of class tank-it works perfectly:
p1 = tank();
p1.checkOri(p1);
if (CONDITION) %the thing I want it to do
p1.value = EXPRESSION;
It works perfectly.
I wonder what caused this. From my experience with other programming languages, invoking method should have worked, is it because of some tricks with Matlab syntax or static method? How could I fix it so that this method would work?
So, as #Navan in the comment said, handle class could be a solution.
It appears Matlab has a similar parameter concept with Java and C++, arguments modified in a function/method only remains that modification inside the function/method.
For this class, I simply added < handle in the head of class definition and it worked:
classdef tank < handle
properties
...
But I am not sure if that is the only solution, there might be better ways to do this. So I'll leave that question open, you are more than welcomed to post your opinion:D
In MATLAB, the call
p1.checkOri();
is equivalent to
checkOri(p1);
In both cases, the class method checkOri is called for the class of object p1, passing p1 as first argument to the function by value.
Because p1 is passed by value, any changes made to it inside the function are not seen by the object in the calling workspace. Therefore, one typically does
p1 = checkOri(p1);
This way, the object that was passed by value and modified inside the function is passed back out and assigned to the variable that held the original object.
If the method is written as follows:
function obj = checkOri(obj)
%...
end
then MATLAB will optimize the above function call such that no copy of the object is actually made. Note that both in the function declaration and in the function call, the input and output variable is the same.
As already discovered by OP, the above does not hold for handle classes, classes that inherit from handle. These classes act as if they are always passed by reference, and any change made to them in any workspace will be reflected in all other copies in other workspaces.
Also assigning to a member variable does not follow the above, such that
p1.value = 0;
modifies object p1.
For more information on the difference between value classes and handle classes see this other question.
Matlab allows for class methods to be both abstract and static, which is different than many OO languages. After trying a few cases, however, it's unclear to me how this can be used in actual code. Consider this sample abstract class:
classdef (Abstract) TestParent
methods (Access = public, Abstract = true, Static = true)
f()
end
methods (Access = public, Static = true)
function g()
disp('Test g');
TestParent.f(); % This line will cause problems
end
end
end
And consider this concrete child class:
classdef TestChild < TestParent
methods (Access = public, Static = true)
function f()
disp('f child');
end
end
end
As noted in the comment on the class TestParent, the call to the abstract static f() will fail at runtime. Specifically, from the command line, using the child class, I get:
>> TestChild.f()
f child
>> TestChild.g()
Test g
Error using TestParent.f
Method 'f' is not defined for class 'TestParent' or is removed from MATLAB's search path.
Error in TestParent.g (line 13)
TestParent.f();
On the command line using the parent class, I get:
>> TestParent.g()
Test g
Error using TestParent.f
Method 'f' is not defined for class 'TestParent' or is removed from MATLAB's search path.
Error in TestParent.g (line 13)
TestParent.f();
So, in summary:
I can call f on the child class with no problem. This makes sense since it has a concrete implementation in the child class. So far so good.
If I try to call g using the parent class name as a qualifier, the code crashes when it needs to call the abstract static method f. This makes sense since the parent has no implementation of f and the call path did not go through any concrete child.
If I try to call g from the child class, it recognizes that the child class has no local method with that name and goes to the parent class, where it finds and attempts to run the parent's implementation of g. In this case, I was expecting it to run successfully since the call path does logically imply a concrete implementation of f that should be run. Nonetheless it crashes.
The last one is the real surprise to me. I expected that if static and abstract meant anything, it would mean that this is supported. Given that this is apparently not supported, I'm unable to see why this combination of keywords makes sense. Can anyone give a use case for this?
I'm new to MATLAB OOP. I have an abstract class defining an abstract method in my matlab path. I have a subclass named SubAbsClass in a subfolder named #SubAbsClass. I cannot create an object of the subclass after implementing the abstract method in the subclass. Here's my SubAbsClass implementation:
classdef SubAbsClass < AbsClass
properties
O1
end
methods
function obj=SubAbsClass(a,b)
obj.O1=absMethod(a,b);
end
end
methods (Static)
function out = absMethod(a,b)
out = a + b;
end
end
end
and my abstract class implementation is:
classdef AbsClass
methods(Abstract, Static)
result = absMethod
end
end
when I try to create an object in the MATLAB path (the abstract class is in the MATLAB path), I get an error. I have tried many configurations and searched the matlab oop document, and also the web including stackoverflow but unfortunately couldn't find an example to implement. I appreciate your help
>> clear all; clear classes;
>> obj=SubAbsClass(5,2)
Undefined function 'absMethod' for input arguments of type 'double'.
Error in SubAbsClass (line 11)
obj.O1=absMethod(a,b);
Within a method, Matlab considers non-dot references to be calls to local functions (defined outside the classdef block within the class file) or to a function somewhere on the Matlab path following the usual look-up rules.
So you need to call the Static method via the instance obj in the constructor:
methods
function obj = SubAbsClass(a,b)
obj.O1 = obj.absMethod(a,b);
end
end
One little caveat to the above is that non-Static methods also have a functional form.
So if the method was not Static, this notation would also work
methods
function obj = SubAbsClass(a,b)
obj.O1 = absMethod(obj,a,b);
end
end
Which, I think, is almost equivalent to the dot notation, although it has been said to be "generally" faster (albeit, that was four years ago).
Here are the details for ordinary method invocation and Static method invocation.
i have a class called sampleClass with a cell array member variable called list.
Now i am trying to add elements to the internal list. For this purpose, i created the method addToList. The method simply tries to add elements to the list.
classdef sampleClass
properties
list = {}
end
methods
function addToList(obj)
obj.list{end+1}='test';
obj.list
end
end
end
Now the problem is, that the elements are not stored in the list.
Inside the function addToList the following output signalizes that the element is stored in the list:
>> samp = sampleClass();
>> samp.addToList
ans =
'test'
But after leaving the function, the element is no longer accessible:
>> samp.list
ans =
{}
Has anybody an idea what's going wrong? I am using Matlab 7.11.0 (R2010b).
Thanks for your help.
Julien
That's because you forgot to inherit from the handle class:
classdef sampleClass < handle %// Change here!
properties
list = {}
end
methods
function addToList(obj)
obj.list{end+1}='test';
obj.list
end
end
end
If you want to retain the changes made when modifying an instance of your class, you must inherit from the handle class. This can be done by taking your class definition (first line of your code), and doing < handle. If you don't, then any changes you make will not be saved. To show that this works, this is what I get in MATLAB:
>> samp = sampleClass();
>> samp.addToList
ans =
'test'
>> samp.list
ans =
'test'
To be more verbose, here's what the MATLAB docs say about handle:
The handle class is the superclass for all classes that follow handle semantics. A handle is a reference to an object. If you copy an object's handle, MATLABĀ® copies only the handle and both the original and copy refer to the same object data. If a function modifies a handle object passed as an input argument, the modification affects the original input object.
As such, you need to inherit from the handle class so that you have a reference back to the object you created. Any changes you make to the instance of your class will be remembered if you inherit from handle. If you don't, no changes you make get registered.
I'm having some trouble creating classes in matlab and I don't really understand the method behind it (i'm fairly new to it)
here is my attempt at basic addition using matlab
classdef test
properties
a
b
end
methods
function add = plus(a, b)
end
end
end
assigning values via
p=test(), p.a=5
etc seems to work fine, however attempting p.add returns the error
No appropriate method, property, or field add for class test.
Any help or guidance would be appretiated, thanks.
Methods are defined exactly as functions are with respect to names and outputs.
Therefore, the method is called plus, the output the method should calculate is called add, and the way you probably wanted to write the method is:
function out = add(this)
out = this.a + this.b;
end
Now you call the method as
p.add();