Implementing an abstract method using a function handle
9 次查看(过去 30 天)
显示 更早的评论
I would like to create a class that has an abstract method that must be implemented by all sub-classes. In my design, some sub-classes may have several possible choices of methods available to them, and the one ultimately implemented is selected in the constructor. Ideally I'd like to define the abstract method using a function handle. Is this possible?
Given an abstract method/class:
classdef (Abstract) mySuperclass
...
methods(Abstract)
myfun(varargin)
end
I'd love to be able to do a single assignment using a function handle in the constructor:
classdef myChoiceSubclass
properties (Access=public)
funtype
end
methods (Access=public)
function out=myChoiceSubclass(varargin)
switch obj.funtype
case 1
obj.myfun = @fun1;
case 2
obj.myfun = @fun2;
...
end
But this does not seem possible. Instead I must do something like this:
classdef myChoiceSubclass
properties (Access=public)
funtype
end
methods (Access=public)
function out=myfun(obj,varargin)
switch obj.funtype
case 1
out=obj.fun1(varargin{:});
case 2
out=obj.fun2(varargin{:});
...
end
end
methods (Access=protected)
function out=fun1(varargin)
...
end
function out=fun2(varargin)
...
end
...
The problem with this approach is that the class must check which function to use every single time it is called, as well as pack and unpack the arguments each time (varargin->varargin{:}->vargin), which is very inefficient. By using a handle, the abstract method would be implemented only once and just treated like a regular method.
Any thoughts?
0 个评论
回答(1 个)
Stephen Jue
2017-4-14
You can achieve something similar to this using an abstract property rather than an abstract method. For example, suppose you have an abstract class called "MathClass" that has an abstract "doMath" property:
classdef (Abstract) MathClass
properties(Abstract)
doMath
end
end
You can then subclass this and dynamically choose a function handle to assign to the "doMath" property, such as "sumNumbers" and "averageNumbers":
classdef MyMath < MathClass
properties
doMath
end
methods (Access=public)
function obj = MyMath(functionNumber)
switch functionNumber
case 1
obj.doMath = @obj.sumNumbers;
case 2
obj.doMath = @obj.averageNumbers;
end
end
function out = sumNumbers(obj, varargin)
out = sum([varargin{:}]);
end
function out = averageNumbers(obj, varargin)
out = mean([varargin{:}]);
end
end
end
Now, you can create an object that has a different implementation for "doMath" depending on how you construct it:
>> summer = MyMath(1);
>> summer.doMath(1,2,3);
ans =
6
>> averager = MyMath(2);
>> averager.doMath(1,2,3);
ans =
2
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Class Introspection and Metadata 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!