Method with struct input: how to accept different object subfields?

Hi all,
In a method, how to accept different object subfields?
https://uk.mathworks.com/help/matlab/matlab_oop/ordinary-methods.html
Above site gives an example of addData method. Code is here:
classdef MyData
properties
Data = 0
end
methods
function obj = addData(obj,val)
newData = obj.Data + val;
obj.Data = newData;
end
end
end
My understanding is when applying addData to object, 'val' can be replaced with any variable to allow different inputs, which is good.
However, if there is another output subfield in obj, say 'Data1', this method cannot be reused to 'Data1', as it will only recognize 'Data' as the subfield here.
Of course I can write a new method:
function obj = addData1(obj,val)
newData = obj.Data1 + val;
obj.Data1 = newData;
end
such that Data1 can also be accepted, but this is cumbersome as the operation is repeated. What is the correct way to allow different struct function output here?
Thank you!

 采纳的回答

I'm not sure I understand fully what you're asking, particularly as you're not using correct terms. There are no structures, fields or subfields in any of the code you've shown (and I've no idea what you mean by output subfield). An object has properties (and methods, and optionally events).
The properties of an objects are defined in the classdef block. While there is a way to have dynamic properties in matlab it's a fairly advanced form of programming which I wouldn't recommend. For the common case the properties are set by the class and the user of the class cannot create more properties.
Also note that in the example you've shown the addData method is not particularly useful since the property is public (i.e. can be modified by users of the class). You could simply bypass it and do:
o = myData; %instantiate object
o.Data = o.Data + val; %modify Data directly without calling addData
I'm not sure what it is you're trying to do. What is your ultimate goal?

10 个评论

I should correct the terms I used: data and data1 are properties of obj, and addData is a method which should apply to both data and data1; but in the method shown here:
classdef MyData
properties
Data = 0
end
methods
function obj = addData(obj,val)
newData = obj.Data + val;
obj.Data = newData;
end
end
end
method addData only applies to property 'data', not data1. How can I make addData apply to data1 as well?
One possible option:
classdef MyData
properties
Data = 0;
Data1 = 0;
end
methods
function obj = addData(obj, propname, value)
assert(isprop(obj, propname), '%s is not a property of the object', propname);
obj.(propname) = obj.(propname) + value;
end
end
end
Which you would then use with:
o = MyData;
o = o.addData('Data', 5);
o = o.addData('Data1', 10);
But as I've already pointed out, you can replace the three lines above by:
o = MyData;
o.Data = o.Data + 5;
o.Data1 = o.Data1+ 10;
which is much simpler and doesn't need the addData method.
I used this sample class from MATLAB documentation to demonstrate a simple case of my question. It's true that for simple cases, we can just use
o.Data = o.Data + 5;
o.Data1 = o.Data1+ 10;
but if the operation here is not a simple '+', but is a complicated one which has to be made into a method, with not just o.Data and o.Data1, but a large number of properties work simultaneously as method inputs, then maybe it's necessary to be able to recognize the propname and apply the method to different properties inputs.
If you are applying the same thing to lots of properties why aren't you just storing them in an array? It sounds like a problem of design before you get to your class if you are needing to do this on any major scale.
Classes do not work well as a way to keep changing lots of properties lots of times. My current algorithm is running excessively slowly because of a lot of property accessing so I will either have to reprogram it to access the properties fewer times or simply remove the class part of it altogether and work on the rawest form of the data I can.
An example:
classdef myProj < handle
properties
propa
propb
end
methods
function obj = myProj(a1, a2, a3, b1, b2, b3)
obj.propa.a1 = a1;
obj.propa.a2 = a2;
obj.propa.a3 = a3;
obj.propb.b1 = b1;
obj.propb.b2 = b2;
obj.propb.b3 = b3;
end
function obj = testCase(obj)
obj.propa.test = obj.propa.a1 .^ 2 + ...
obj.propa.a2 * sum(obj.propa.a1(:)) - ...
obj.propa.a1 / norm(obj.propa.a3, 'fro');
end
end
end
and the script to build the object is:
clear; clc;
a1 = randi(5, 5);
a2 = randi(5, 5);
a3 = randi(5, 5);
b1 = randi(3, 3);
b2 = randi(3, 3);
b3 = randi(3, 3);
proj1 = myProj(a1, a2, a3, b1, b2, b3);
proj1.testCase;
I would like method 'testCase' to apply to data in propb, but it will not work unless I modify testCase to:
function obj = testCase(obj)
obj.propb.test = obj.propb.b1 .^ 2 + ...
obj.propb.b2 * sum(obj.propb.b1(:)) - ...
obj.propb.b1 / norm(obj.propb.b3, 'fro');
end
which is obviously a duplicate to original testCase.
As Adam said, all your problems come from bad design. A simple rule: if you're numbering variables, your design is wrong. These numbered variables should be replaced by a matrix/cell array/similar container.
In your case:
classdef myproj < handle %you seem to have switched to handle class but still use value class syntax for your method
properties
container = cell(2, 3);
test
end
methods
function this = myproj(a1, a2, a3, b1, b2, b3) %and even here accepting a cell array would be simpler
%class constructor
this.container = {a1, a2, a3; b1, b2, b3};
end
function testcase(this, aorb) %handle syntax
row = ismember(aorb, {'a', 'b'})
this.test = this.container{row, 1) .^ 2 + ...
this.container{row, 2) * sum(this.container{row, 1}(:) - ...
this.container{row, 1} / norm(this.container{row, 3}, 'fro');
end
end
end
ismember here is used to determine row number of a or b, which should give 1 for a, 2 for b, but it seems to give 1 regardless input a or b.
Yes, slight bug, but you get the idea. Note that in real code, I wouldn't use char arrays as toggles, I would either pass the numeric index of the row directly or use categoricals.

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Tables 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by