Implementing an abstract method using a function handle

조회 수: 16 (최근 30일)
Michael
Michael 2017년 4월 11일
답변: Stephen Jue 2017년 4월 14일
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?

답변 (1개)

Stephen Jue
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

Community Treasure Hunt

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

Start Hunting!

Translated by