技术文章和通讯

介绍在MATLAB面向对象编程

Stuart McGarrity和Adam Sifounakis, MathWorks


在创建软件应用程序时,将软件的各种构建块组织到相关的组中是很重要的。例如,自定义数值求解器可能需要几个配置参数和例程来执行完整的计算集。面向对象编程(OOP)允许您将求解器的配置参数(属性)及其函数(方法)组合成单个定义或.用户正确执行此求解器所需的一切都在该类中定义。

对象是类的实例。当程序执行时,对象根据其类定义创建,并按照类定义的方式进行行为。对象的属性表示它的状态,它的方法表示用户可能执行的所有操作。通过这种方式,代码作者可以很容易地对软件系统的所有相关数据和功能进行分组,用户也可以很容易地找到和使用代码作者开发的所有功能。

下面的示例使用编程来构建应用程序,将分析来自传感器阵列的传感器数据的面向对象的。

应用示例:分析传感器阵列数据

的传感器阵列(图1)是传感器的集合,通常布置成一条线,其用于采样的介质,如空气,水,或用于雷达地面,声纳,或蜂窝通信。通过在空间中从多个点收集的时间样本,则可以从培养基中被采样中提取附加信息。

图1所示。以未知角度探测两个远距离电磁源的传感器阵列。

我们的应用程序使用传感器阵列来确定多个远程电磁源(如无线电信标和雷达发射机)的到达方向(DOA)。在这种情况下,我们将尝试估计两个源相对于传感器阵列指向的方向的角度θ1和θ2。

检查数据项目和操作

对于这个应用程序,我们需要存储和表示以下数据:

  • 传感器和样品的数量
  • 采样传感器数据
  • 传感器的采样率
  • 传感器间距
  • 遥远的来源波长
  • 波的速度
  • 传感器数据集名称或描述

我们将使用一种简单的基于快速傅里叶变换(FFT)的技术来估计源的DOA。该技术可以分解为多个部分,并作为操作集合实现。将实现少量实用程序操作,以帮助简化开发工作。例如,我们必须:

  • 创建合成数据或获取的实时数据的数据集
  • 检查和修改数据集的值和参数
  • 与解释和验证绘制样本数据,以帮助
  • 计算和绘制数据集的功率谱(通过FFT方法的简单幅度平方)
  • 找出功率谱的峰值来估计源的DOA

确定了需要表示的数据和需要执行的活动之后,我们就可以用类属性表示数据,用类方法表示活动。

用类属性表示数据

我们首先定义一个类来描述传感器阵列。这个初始表示仅包含数据项,并将它们表示为类属性。

用类定义文件在MATLAB中定义一个类,该文件以classdef关键字和由终止结束关键词。在类定义块,追加关键词块将描述类的不同方面,如类属性和类方法。在图2所示的定义文件描述了一类SADS(传感器阵列数据集),我们需要在属性块中列出的所有数据项。

图2。类定义文件sads.m与性能。

创建对象并访问属性

要创建所定义类的对象或实例,可以使用该语句

>> S = SADS;

要设置属性的值,我们可以指定它的名称,就像结构的字段一样

>> . numsensors = 16;

我们可以通过输入对象的名称来显示对象,查看所有可用的属性和当前值。

>> S S =具有属性SADS:波长:[] C:3亿个NumSensors:16个NUMSAMPLES:[]数据:[α]间距:[] SAMPLERATE:[]名称:[]

所有属性除NumSensorsc仍然是空的。数据集现在可以被识别为SADS对象使用函数,isa功能,命令,这在结构中是不可能的。

>> class(s) ans = 'sads'

对于创建代码来操作数据集的用户来说,识别变量类的能力非常重要,因为它允许他们确定要访问的可用数据项和可以合法执行的操作。

错误检查

如果你使用的结构来表示你的数据,你可以简单地通过指定一个新的字段名称,并分配一个值,随时添加新的字段名称。这种能力是特别方便,当你与实验和原型算法。但是,如果你拼错字段名称,新的字段将被添加默默地,这可能会在以后导致错误是很难诊断。

与结构不同,不能简单地通过指定新属性名并为其赋值来动态地向对象添加新属性。如果你拼错了一个对象属性名,MATLAB会立即发出一个错误。当对象被不像作者那样熟悉它的用户访问时,这种额外的错误检查级别是很有用的,这在大型应用程序开发期间是很常见的。

控制对数据的访问

类可以让您对属性访问控制很大。例如,他们让你禁止的属性修改,隐藏属性,或导致其被动态计算。您可以通过在类定义文件中指定属性的属性控制访问性能。通过将属性的当前列表分为多个属性块,每个具有独特的属性的属性,我们在图2中的类定义文件扩展:GetAccess的持续的, 和依赖的(图3)。

图3。类定义文件sads.m与财产属性。

属性的值可以禁止修改属性持续的属性。在我们的例子中,我们将设置光速属性c恒定。因为不断性质不改变,他们可以简单地通过引用类名访问。

>> sads.c ans = 300000000

你让一个属性只读通过设置SetAccess私有属性。属性的值可以使属性仅对操作它的方法可见GetAccess的属性为private,就像我们将处理的波长财产。

您可以自由改变私有财产的名称或特性,而不影响对象的用户。这个“黑盒子”的方式来限定的软件,被称为封装,防止对象物的用户变得依赖于实现的细节或可能会改变,并打破它们的码的特性。

通过设置其属性,指定仅在请求时计算属性依赖的属性。

然后指定一个get方法,该方法在访问属性时自动调用。看到使用Get和Set方法访问属性章节中详细介绍了如何指定类方法。在我们的应用程序中,我们设置NumSensorsNumSamples属性是依赖。

用类方法实现运营

方法或可在对象上执行的操作被指定为方法块中的函数列表。一个类可以包含多种类型的方法,每种方法实现不同的目的,每种方法的指定方式不同。下面的部分描述了许多这类方法。

将方法块添加到SADS定义文件并将每个新方法添加到这个块中(图4)。

图4.类定义文件sads.m与方法,显示在MATLAB编辑器。为了便于查看,代码折叠特性用于隐藏大部分代码。

指定构造函数方法

在我们的示例中,我们将指定一个构造函数方法,该方法允许用户提供在创建对象时使用的参数。构造函数方法通常执行数据初始化和验证。对象现在是用

>> S = SADS(数据,波长,采样率,间距,名称);

实现特定于应用程序的方法

我们将添加几个方法来实现在数据集上执行的特定于应用程序的操作。大多数方法将对象作为输入参数(例如,obj)并访问通过参照该变量的对象属性(例如,obj.NumSamples),如在以下方法中:

功能Mag = [mags,fflip] = magfft(obj, zpt) Mag = 0 (obj, zpt)NumSamples、zpt);...结束

虽然它需要额外的语法,但通过对象变量引用属性可以帮助将它们与局部函数变量区分开来,例如玛格以上。

调用方法

方法像函数一样被调用,对象作为参数传入。我们可以通过调用doa我们班的方法。

>> angle = doa(s) angle = -10.1642 18.9953

DOA角近似于图1所示的源的真实位置,分别为-10°和20°。

访问与get和set方法属性

您可以验证属性或通过指定组相关的实施依赖属性和get方法。下面是get方法NumSensors财产。

功能NumSensors = get.NumSensors(OBJ)NumSensors =尺寸(obj.Data,2);结束

在访问属性时自动调用Get和set方法,例如使用

>> N = s.NumSensors;

使用重载指定已有MATLAB函数的方法

超载,您可以通过在方法列表提供使用该名称的功能重新定义现有的MATLAB功能,在对象上工作。在我们的应用中,我们将有一个重载情节方法,提供了一个功能,以可视化数据集所熟悉的许多MATLAB用户(图5)。

> >的情节(s)

图5.重载plot方法专门用于传感器阵列数据集。

这个定制的绘图方法以最适合该数据集的方式表示信息,并用所有可用信息对其进行注释。它只在定义了它的对象上执行——这是一种比操纵路径中的目录顺序更健壮的方法。

如果您想专门针对行为的类,你也可以重载基础运营商甚至可以通过使用方法具有特殊名称索引。

进一步开发应用程序

我们在本例中创建的类表示传感器阵列数据集,并允许我们轻松地对数据执行复杂的专门分析,包括主要的测向操作。我们可以使用这个类来快速评估基于fft的技术在不同场景下的性能。

我们可以使用其他的OO技术扩展应用程序。例如,我们可以这样做:

  • 定义已有类的子类(重用更广泛类别的定义来定义一个更具体的子类)具有继承
  • 指定静态方法,让我们可以为整个类定义一个操作
  • 使用手柄类参考行为,使我们能够像链表或工作有一个大的数据集的数据结构,但没有照搬
  • 定义事件和监听器,让我们监视对象的属性或行动

这些技术通过使我们能够进一步定义应用程序中的关系和行为,增强了我们管理复杂性的能力。

因为它是使用OO技术构建的,所以应用程序现在已经足够健壮,可以供其他人使用和维护,并且可以与整个组织中的其他应用程序集成。

2020年出版的

查看文章的相关能力

查看相关行业的文章