フィルターのクリア

Unable to set dynamic property within superclass method from subclass object

4 ビュー (過去 30 日間)
Rob
Rob 2013 年 7 月 3 日
編集済み: men8th 2022 年 5 月 18 日
I'm unable to set the value of a dynamic property within a superclass method called from a subclass object. Defining a superclass and subclass as follows...
% Superclass definition:
classdef MySuperClass < dynamicprops
methods
function addMyProp(obj, myVal)
if ~isprop(obj, 'myProp')
myPropHandle = addprop(obj, 'myProp');
myPropHandle.SetAccess = 'protected';
end
obj.myProp = myVal; % <--- Error occurs here.
end
end
end
% Subclass definition:
classdef MySubClass < MySuperClass
end
The problem occurs when I attempt to assign myVal to the newly created dynamic property myProp within the superclass method addMyProp from the subclass object:
obj = MySubClass;
obj.addMyProp(123);
I get the following error:
Setting the 'myProp' property of the 'instance' class is not allowed.
If I change the SetAccess attribute to public instead of protected, I don't get an error:
myPropHandle.SetAccess = 'public';
This is strange to me because I thought protected meant that subclasses could set that property too. Plus, I really don't want access to that property to be public.
What am I missing?
Thanks,
Rob
(R2010b)

回答 (2 件)

per isakson
per isakson 2013 年 7 月 3 日
This restriction is not specific to dynamic properties. The documentation says:
protected — access from class or subclasses
it doesn't explicitly include superclasses. I assume, this is intended behavior.
  2 件のコメント
Rob
Rob 2013 年 7 月 3 日
Thanks, Per!
Ah, so the issue is that the superclass is unable to assign a value to the property myProp because myProp is a subclass property, not a superclass property, and making its SetAccess attribute protected means that only the subclass and classes derived from the subclass can set its value? I guess I thought, erroneously, that because the property was created within a superclass method it became a superclass property.
-Rob
men8th
men8th 2022 年 5 月 18 日
編集済み: men8th 2022 年 5 月 18 日
I've just worked through a similar problem. I wanted to call a superclass constructor from a subclass, initialise some dynamic properties in the superclass constructor, then retun the object to the subclass constructor for further use. The problem is that when you call the superclass constructor, the object you are constructing is an object of the same type as the subclass. When you create a dynamic property in the superclass constructor you are creating a property for the subclass object.
classdef mySub < mySuper
function obj = mySub
obj = obj@mySuper(arg1,arg2) % Call superclass constructor
end
end
classdef mySuper < dynamicprops
function obj = mySuper(arg1,arg2)
% Superclass constructor builds an object of class mySub
dynPropObj = obj.addprop("dynPropName"); % ==> mySub.dynPropName
dynPropObj.SetAccess = "protected";
% Fail here because obj has class mySub, not mySuper, so the
% dynamic property is a property of mySub. Shouldn't really set
% a subclass property from a superclass. Can't do it here anyway
% because it is protected.
obj.dynPropName = arg1;
end
end
This makes sense to me because a superclass should not be able to interfere with a subclass property. In general, a superclass wouldn't even know about a subclass property because inheritance goes in the direction superclass-->subclass, not subclass-->superclass.
In my instance, I was able to work round this by setting the property value first, then setting access to protected afterwards. This does mean though that you are not able to access the property from the superclass later on.

サインインしてコメントする。


Matt J
Matt J 2013 年 7 月 3 日
編集済み: Matt J 2013 年 7 月 3 日
Looks like a bug to me. Here's a workaround, though,
classdef myclass < dynamicprops
methods
function myPropHandle = addMyProp(obj, myVal)
if ~isprop(obj, 'myProp')
myPropHandle = addprop(obj, 'myProp');
myPropHandle.SetAccess = 'protected';
else
myPropHandle = findprop(obj, 'myProp');
end
if nargin>1,
obj.myProp = myVal;
end
end
end
end
and then overload addMyProp in the subclass, but only the part that sets access to 'protected' and sets myVal,
classdef mysubclass < myclass
methods
function addMyProp(obj, myVal)
myPropHandle = addMyProp@myclass(obj);
myPropHandle.SetAccess = 'protected';
obj.myProp = myVal;
end
end
end
  2 件のコメント
Rob
Rob 2013 年 7 月 3 日
Thanks for the suggestion, Matt! I'll try that as a workaround. Alternatively, since multiple subclasses of MySuperClass will want to call the addMyProp method, I suppose I could change the attribute to public, assign the value, and change the attribute immediately back to protected, all within the superclass:
myPropHandle.SetAccess = 'public';
obj.myProp = myVal;
myPropHandle.SetAccess = 'protected';
It's not elegant, but I'd rather not have to overload the addMyProp method in each subclass of MySuperClass. Anyway, I'll try your solution first.
-Rob
Matt J
Matt J 2013 年 7 月 3 日
That looks like a fine alternative, as long as you're not doing asynchronous things with the class, e.g.,as with GUI callbacks and such...

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeClass File Organization についてさらに検索

タグ

製品

Community Treasure Hunt

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

Start Hunting!

Translated by