Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 构造没有输入参数的对象数组 背景_Arrays_Matlab_Object_Constructor_Superclass - Fatal编程技术网

Arrays 构造没有输入参数的对象数组 背景

Arrays 构造没有输入参数的对象数组 背景,arrays,matlab,object,constructor,superclass,Arrays,Matlab,Object,Constructor,Superclass,我有不同类型的文件,我从中提取并存储数据,例如.csv和数据库文件。它们通常是大文件,我已经有了从中提取数据的适当方法 期望的行为 让我们以类textfile为例。我希望能够创建一个textfile对象数组,其中每个元素对应一个唯一的文本文件。我希望能够使用单个参数调用textfile,或者根本不调用任何参数 如果我没有传递任何参数,我将被带到文件选择屏幕来选择文件,并将创建一个对象数组,为我选择的每个文件创建一个元素 如果传递了一个参数,我希望根据该参数是什么来创建数组。如果是目录路径,请再次

我有不同类型的文件,我从中提取并存储数据,例如.csv和数据库文件。它们通常是大文件,我已经有了从中提取数据的适当方法

期望的行为 让我们以类
textfile
为例。我希望能够创建一个
textfile
对象数组,其中每个元素对应一个唯一的文本文件。我希望能够使用单个参数调用
textfile
,或者根本不调用任何参数

  • 如果我没有传递任何参数,我将被带到文件选择屏幕来选择文件,并将创建一个对象数组,为我选择的每个文件创建一个元素

  • 如果传递了一个参数,我希望根据该参数是什么来创建数组。如果是目录路径,请再次打开文件选择屏幕。如果是文件路径的单元格数组,请创建这些文件的对象数组

  • 我希望能够轻松创建更多具有相同基本行为的类,如
    textfile

    迄今为止的尝试 我定义了一个超类
    file
    ,以处理所有文件的共同行为。这包括分配属性,如
    文件名
    扩展名
    。我的其他类都是
    文件
    的子类

    文件
    的构造函数中,我有两个输入参数。我的想法是,在相关的子类构造函数中,我将调用
    文件
    构造函数。第一个输入参数是文件类型,例如
    txt
    ,而第二个输入参数是我在创建
    textfile
    数组时选择的参数。为简单起见,假设我希望能够处理的
    arg
    的唯一类型是从中选择文件的目录路径

    classdef textfile < file
        methods
            function textfileObject = textfile(arg)
                if nargin == 0
                    arg = '';
                end
                textfileObject@file('txt',arg);
        end
    end
    
    arg
    是一个目录时,这会起作用,因为当对象数组在
    textfile
    中初始化时没有输入参数,
    arg
    被设置为
    '
    ,这与其余构造函数一起工作

    然而,我希望在创建
    textfile
    对象时不能有任何输入参数,但这对于构造函数的无输入参数规则是不起作用的

    问题 是否有一种方法可以在

  • 调用超类构造函数和

  • 不使用任何输入参数

  • 我对其他解决方案持开放态度,这些解决方案可以帮助我解决为每种文件类型创建类的问题

    解决方案 事实证明,您可以使用匿名函数从超类调用子类构造函数。实际上,您可以在没有输入参数的情况下调用子类构造函数,然后在使用这些文件名作为输入再次(递归)调用子类之前在超类中生成文件名。谢谢@Suever

    子类构造函数将是:

    classdef textfile < file
        methods
            function textfileObject = textfile(varargin)
                textfileObject@file('txt',varargin{:});
            end
        end
    end
    
    classdef textfile
    在超类中:

    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
    
    classdef文件
    实现这一点的方法是递归调用类的构造函数来生成
    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
    

    实现这一点的方法是递归调用类的构造函数来生成
    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
    

    因此,当您未提供任何输入时,系统会提示您选择文件?@Suever Yes,当我未提供任何输入时,系统会提示您选择文件(默认情况下从工作目录),然后,将使用我选择的文件对应的每个元素创建对象数组。因此,如果您不提供输入,则系统会提示您选择文件?@Suever Yes,如果我不提供输入,则系统会提示我选择文件(默认情况下,从工作目录),然后将创建对象数组,每个元素对应于我选择的文件。谢谢你的回答!这就解决了
    textfile
    类的问题。唯一不好的是,这意味着我必须在给定文件类型的每个类中编写这段代码,这就是为什么我认为最好使用
    file
    超类来处理所有这些。当我想使用
    文件
    超类构造函数来处理文件选择时,有没有一种方法可以使用您的方法?@spaggy我添加了一个示例,说明如何从超类执行此操作问题是我只想调用超类构造函数一次,但是在子类中调用超类构造函数不能在条件块中完成。这意味着每当超类构造函数调用子类时(根据
    cellfun
    ,在
    filelist
    中的每个文件调用一次),超类构造函数也将被调用……@Jens为什么只调用超类构造函数一次?我已经说过了
    constructor = @(varargin)feval(class(self), varargin{:});
    output = cellfun(constructor, filelist, 'uniformoutput', 0);