我有不同类型的文件,我从中提取并存储数据,例如.csv和数据库文件。它们通常是大文件,我已经有适当的方法从中提取数据。
让我们以班级textfile
为例。我希望能够创建一个textfile
个对象数组,其中每个元素对应一个唯一的文本文件。我希望能够用一个参数调用textfile
,或者根本没有参数。
如果我不传递任何参数,我将被带到文件选择屏幕以选择文件,并将创建一个对象数组,我选择的每个文件都有一个元素。
< / LI>如果传递了一个参数,我希望根据参数是什么来创建数组。如果是目录路径,请再次打开文件选择屏幕。如果它是文件路径的单元格数组,请创建这些文件的对象数组。
我希望能够轻松创建更多具有相同基本行为的textfile
类。
我已经定义了一个超类file
来处理所有文件的共同行为。这包括分配filename
和extension
等属性。我的其他类都是file
的子类。
在file
的构造函数中,我有两个输入参数。我的想法是,在相关的子类构造函数中,我调用file
构造函数。第一个输入参数是文件类型,例如txt
,而第二个是我在创建textfile
数组时选择的参数。为简单起见,我们说我希望能够处理的唯一arg
类型是从哪里选择文件的目录路径。
classdef textfile < file
methods
function textfileObject = textfile(arg)
if nargin == 0
arg = '';
end
textfileObject@file('txt',arg);
end
end
file
构造函数取决于创建arg
对象时textfile
的内容,根据using the No Input Argument Constructor Requirement生成对象数组。
classdef file < handle
properties
Path
end
methods
function FileObject = file(FileType,arg)
if nargin == 2
FileList = file.SelectFiles(FileType,arg);
FileObject(numel(FileList),1) = file;
for filecount = 1:numel(FileObject)
FileObject(filecount,1).Path = FileList{filecount};
end
end
end
end
methods(Static)
function FileList = SelectFiles(DirectoryPath)
% Some selection dialogs. Returns a cell array of filepaths
end
end
end
当arg
是一个目录时,这是有效的,因为当textfile
中没有输入参数的对象数组被初始化时,arg
被设置为''
,它与其余的建设者。
但是,我希望在创建textfile
对象时不能有任何输入参数,但这并不适用于构造函数的No Input Argument规则。
有没有办法在
时创建对象数组调用超类构造函数和
不使用任何输入参数?
我可以使用其他解决方案来解决我为每种文件类型创建类的问题。
事实证明,您可以使用匿名函数从超类中调用子类构造函数。实际上,您可以在没有输入参数的情况下调用子类构造函数,然后在使用这些文件名作为输入再次(递归地)调用子类之前,在超类中生成文件名。谢谢@Suever。
子类构造函数将只是:
classdef textfile < file
methods
function textfileObject = textfile(varargin)
textfileObject@file('txt',varargin{:});
end
end
end
在超类中:
classdef file < handle
properties
Path
end
methods
function FileObject = file(FileType,varargin)
% Subclass constructor handle
Constructor = @(FilePath)feval(class(FileObject),FilePath);
% No subclass arguments
if nargin == 1
FileList = file.SelectFiles(FileType,'');
for a = 1:numel(FileList)
FileObject(a,1) = Constructor(FileList{a});
end
% One subclass argument
elseif nargin == 2
arg = varargin{1};
if ischar(arg)
FileStruct = dir(arg);
if numel(FileStruct) == 1
FileObject.Path = arg;
end
end
% Too many subclass arguments
else
error('Subclasses of file only take one or no input arguments');
end
end
end
end
答案 0 :(得分:1)
执行此操作的方法是递归调用类的构造函数以生成textfile
个对象的数组。
classdef textfile < file
methods
function self = textfile(arg)
if ~exist('arg', 'var')
% Get list of files somehow
[fnames, pname] = uigetfile('MultiSelect', 'on');
filelist = fullfile(pname, fnames);
% Call the constructor again for each file
output = cellfun(@textfile, filelist, 'uniformoutput', 0);
% Flatten the cell array of objects into an array of the right shape
self = reshape([output{:}], size(filelist));
else
% Do default construction here
self = self@file('txt', arg);
end
end
end
end
如果要在基类中实现它,可以将递归调用更改为类似以下内容,从file
超类中调用正确的子类构造函数
constructor = @(varargin)feval(class(self), varargin{:});
output = cellfun(constructor, filelist, 'uniformoutput', 0);