专门为略有不同的数据结构定义子类

时间:2018-07-24 17:56:44

标签: matlab class oop inheritance subclass

我决定开始使用OOP来使代码更具模块化,但是我仍然需要学习很多有关最佳实践的知识。

当前数据结构

在这种特殊情况下,我试图定义一个类层次结构,该类层次结构处理(在最低级别上)各种传感器的二进制示波器数据。独立于传感器特性,我定义了类ScopeData,该类仅读取二进制文件并返回x和y数据以及一些通用特性:

classdef ScopeData

    properties
        Filename
        xdata
        ydata
    end

    properties (Access = private)
        % Some properties only used to extract data from the binary file
    end

    properties (Access = protected)
        fid = -1 % used in reading data and closing upon destruction

        % Properties that are required to quickly navigate to the data
        % locations in the binary file
    end

    properties (Dependent = true)
        Raw % raw data 
    end

    %% Methods related to constructing/destructing
    methods
        function obj = ScopeData(filepath)

            % Input argument checking is done here

            % Assign the filename
            obj.Filename = filepath;

            % Open the file and read its contents
            obj.Open;
            obj.Read;
        end


        function obj = Open(obj)
            % Opens obj.Filename and extracts all info required to read out
            % the data
        end

        function obj = Read(obj)
            rawdata = obj.Raw; % get the raw data

            % Some minimal processing and averaging to get xdata and ydata
            obj.xdata = SomeFunction(rawdata);
            obj.ydata = SomeOtherFunction(rawdata);

        end
    end

    %% Get/set methods
    methods
        function rawdata = get.Raw(obj)
            % uses the private properties to efficiently extract the raw data
        end
    end

end

对于每种不同类型的传感器,我创建了继承自SensorXYZData的子类ScopeData。它们的其他属性都是特定传感器所独有的,可用于进一步处理数据,例如:

classdef SensorXData < ScopeData

    properties
        % Sensor-specific properties
        SensorLocation
        SensorConfiguration
    end

    properties (Dependent = true)
        % Sensor-specific dependent properties
    end

    methods
        function obj = SensorXData(filepath, SensorLocation, SensorConfiguration)
            % Initialize object
            obj = obj@ScopeData(filepath);

            % Assign sensor-specific properties

            % Do some additional processing

        end
    end

    methods
        % Get/set methods for the dependent properties
    end

end

上述数据结构使我可以为所有读取单个二进制文件的传感器定义单独的对象。我目前在类文件之外为每个传感器系列创建对象数组。原始数据不会存储,但可以轻松请求。

我要做什么

在不同的传感器系列中,只有 SensorX 系列将处理单个传感器的单个数据文件(默认)和多个传感器的多个数据文件(不同类型的实验)。 在每个文件的基础上,后者将需要与前者完全相同的处理,但是在多文件情况下,还会有其他属性和处理步骤。

我目前正在尝试通过具有一个继承自SensorXArrayData的附加子类SensorXData来实现这种特殊情况:

classdef SensorXArrayData < SensorXData

    properties
        ExtraProperties
    end

    properties (Dependent = true)
        % Dependent variables specific to this data
    end

    methods
        function obj = SensorXArrayData(MultipleFilepaths, SensorLocation, SensorConfiguration, ExtraProperties)
            % Initialize object - I am only allowed to call obj@SensorXData once, so this currently doesn't work.
            obj = obj@SensorXData(MultipleFilepaths, SensorLocation, SensorConfiguration);

            % Assign the extra properties

            % More processing that is specific

        end
    end

    methods
        % Get/set methods for the dependent variables
    end

end

为了使上述工作正常进行,需要采取一些其他步骤,我正在尝试找出最合适的方法。

一种选择似乎是使ScopeData超类与多文件输入兼容并从那里开始工作。还有没有办法让我ScopeDataSensorXData保持不变?

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找的是类中的“实现接口”(Java术语)。在MATLAB中的工作方式是使用multiple inheritance,如下所示:

classdef ClassName < SuperClass1 & SuperClass2

我认为,近年来OOP中的共识是所谓的“ composition over inheritance”,这基本上意味着您应该专注于课程所做的,而不是您的课程类

如何将其应用于您的问题?

添加几个看起来像这样的类:

classdef (Abstract) SomeFeatureInterface < handle
% This is a specialized interface for doing operation XYZ.
  properties (Abstract = true, Access = protected, Constant = true)
    SOME_CONSTANT;
  end  

  methods (Abstract = true, Access = public) % This doesn't have to be abstract, you can add a
    outName = methodName(obj)                % default implementation if relevant.
  end

end

然后,派生类的声明将看起来像购物清单,也就是说,您可以通过继承相关接口(抽象)类来添加类声明中所需的任何功能:

classdef SensorXData < ScopeData & SingleFileInterface & MultiFileInterface

classdef SensorYData < ScopeData & SingleFileInterface

通过这种方式,SensorXData将包含处理多个文件的相关功能,而SensorYData则不会。此外,这将确保浅继承,这被认为是很好的。