OOP: Reference (subclass) enumeration names from static superclass method. Possible?

9 ビュー (過去 30 日間)
Hi, I'm stuck on a MATLAB OOP problem.
I have several enumeration classes that are subclasses to (the abstract) MySuperClass. For Example:
classdef MyEnum1 < MySuperClass
methods(Static)
function result = doWork()
allNames = string(enumeration('MyEnum1'));
result = foo(allNames);
end
end
enumeration
A
B
C
end
end
classdef MyEnum2 < MySuperClass
methods(Static)
function result = doWork()
allNames = string(enumeration('MyEnum2'));
result = foo(allNames);
end
end
enumeration
D
E
F
end
end
% and so on...
Then there is one function which all enumeration classes have in common, that does some work on the enumeration members names, in this case it's the static method doWork(), which is shown above.
I feel like it should be possible to define this method in the (abstract) superclass, since it does the same thing every time and only operates on a different list of enumeration member names, which is dependent on the subclass calling the function. But I can't figure out how to dynamically reference the subclass that is calling the static method.
The following solution seems to work, but I'm giving up the (Static) of my method. Ideally, I would prefer a solution in which I can doWork without having to create an instance of the respective subclass/enumeration class.
classdef(Abstract) MySuperClass
methods
function result = doWork(obj)
allNames = string(enumeration(obj)); % could work, but is not preferred
result = foo(allNames);
end
end
end
What I really want is something like this:
classdef(Abstract) MySuperClass
methods (Static)
function result = doWork
allNames = string(enumeration(?????)); % this?/self?/metaclass?
result = foo(allNames);
end
end
end
so that I may finally use the static method of the superclass as follows:
MyEnum1.doWork
MyEnum2.doWork
%... and so on
Without having to copypaste identical code into each enumeration's classdef.
Thank you so much in advance for your insights!

採用された回答

Matt J
Matt J 2021 年 6 月 7 日
編集済み: Matt J 2021 年 6 月 8 日
No, you can't unfortunately, but you can avoid copying the method to all the sub-classdef's just by making doWork() an external method (i.e., not a method of a class):
function result = doWork(classname)
allNames = string(enumeration(classname)); % this?/self?/metaclass?
result = foo(allNames);
end
You might consider putting all your classdefs in a common folder, and the doWork.m file in a private/ subfolder., so that it will be visible only to this family of classes.
  1 件のコメント
Oliver Grossmann
Oliver Grossmann 2021 年 6 月 8 日
I guess this is the most sensible answer for my case, thank you for this answer.

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

その他の回答 (2 件)

Jeff Miller
Jeff Miller 2021 年 6 月 7 日
If doWork really just needs the names, maybe pass allnames as an argument of doWork, something like this:
function result = doWork(allNames)
result = foo(allNames);
end
% and use it like
doWork(enumeration(MyEnum1))
% or
MySuperClass.doWork(enumeration(MyEnum1))

Captain Karnage
Captain Karnage 2023 年 4 月 27 日
If your goal is to make this function only accessible from the superclass and its subclasses, and you want to just be able to edit the superclass function when you need to make changes, then I have an alternative. The downside is you still have to create the method in all your subclasses, and you have to pass a variable between them - however, it is a single line of code in the subclasses that you just need to follow the pattern on.
You can overload the superclass method with a subclass method of the same name, and use @ to call it. You can then pass an empty version of the calling subclass to give the superclass something to reference.
Here is my example. Just to keep it clear, instead of using the standard variable name obj, I named it subObj because it doesn't fit the conventional context of obj, which should only be used in a non-static method (though MATLAB doesn't actually care what you name it).
I also made this a non-abstract example - if you want to keep MySuperClass as Abstract, then remove the default value of = MySuperClass.empty in the arguments block as you can't create an abstract object.
classdef MySuperClass
methods(Static)
function result = doWork(subObj)
arguments
subObj MySuperClass = MySuperClass.empty
end
allNames = string( enumeration(subObj) );
result = foo(allNames);
end
end
end
classdef MyEnum1 < MySuperClass
methods(Static)
function result = doWork()
result = doWork@MySuperClass(MyEnum1.empty);
end
end
enumeration
A
B
C
end
end
classdef MyEnum2 < MySuperClass
methods(Static)
function result = doWork()
result = doWork@MySuperClass(MyEnum2.empty);
end
end
enumeration
D
E
F
end
end
In order to make this run as a live script on the site, I hadd to create an arbitrary foo function. Here, I just make it horizontally concatenate the names into a cell array.
function result = foo(names)
result = names';
end
By using an arguments block in the superclass, it ensures only an object of its type (which includes subclasses of its type) can be passed and further, if no object is passed (e.g. you're calling the static method using MySuperClass.doWork a.k.a. the "normal" way) it will create an empty version of itself to check and will return its own enumeration, if it has one and return No enumeration members for class MySuperClass if it has none (like in this example).
MyEnum1.doWork
MyEnum2.doWork
Hmm... it won't run Live on here for me for some reason, but I just did an exact copy/paste of everyting in MATLAB 2022b and it worked. I got "A" "B" "C" and "D" "E" "F" as outputs.
  5 件のコメント
Oliver Grossmann
Oliver Grossmann 2023 年 4 月 28 日
What an interesting approach, using the arguments block. Thank you!
Captain Karnage
Captain Karnage 2023 年 5 月 10 日
@Oliver Grossmann I typically use an arguments block whenever I want one or more arguments to match a certain type. In this case, I wanted to make sure that the object being passed to the static function was one of the subclasses. By using the superclass as the validation type, it accepts the superclass or any of its subclasses as an argument and will reject others.
That being said, it's not strictly necessary to this example. You could remove it and it will still work - you just may not be able to predict the results of passing another kind of object to the function.

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

カテゴリ

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

製品


リリース

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by