为属性实现 set/get 接口
标准 set/get 接口
一些 MATLAB® 对象(如图形对象)实现基于 set
和 get
函数的接口。这些函数支持在单个函数调用中访问对象数组的多个属性。
您可以通过从以下类之一派生,将 set
和 get
功能添加到您的类中:
matlab.mixin.SetGet
- 当您要支持不区分大小写的属性名称部分匹配时使用。即使属性派生自matlab.mixin.SetGet
,使用圆点表示法引用属性时,仍需提供确切的属性名称。matlab.mixin.SetGetExactNames
- 当您只想支持区分大小写的属性名称完全匹配时使用。
注意
本节中提到的 set
和 get
方法不同于属性的 set 和 get 访问方法。有关属性访问方法的信息,请参阅属性 get 和 set 方法。
子类语法
使用抽象类 matlab.mixin.SetGet
或 matlab.mixin.SetGetExactNames
作为超类:
classdef MyClass < matlab.mixin.SetGet ... end
由于 matlab.mixin.SetGet
和 matlab.mixin.SetGetExactNames
派生自 handle
类,因此您的子类也是 handle
类。
get 方法语法
get
方法使用对象句柄和属性名称返回对象属性值。例如,假设 H
是对象的句柄:
v = get(H,'PropertyName');
如果您指定一个属性名称和一个句柄数组,get
会以值的元胞数组形式返回每个对象的属性值:
CV = get(H,'PropertyName');
无论 H
的形状如何,CV
数组始终是一列。
如果指定一个属性名称的 char
向量元胞数组和一个句柄数组,get
将返回属性值的元胞数组。元胞中的每行对应于句柄数组中的一个对象。元胞中的每列都对应一个属性名称。
props = {'PropertyName1','PropertyName2'}; CV = get(H,props);
get
返回 m×n 元胞数组,其中 m = length(H)
且 n = length(props)
。
如果指定句柄数组,但未指定属性名称,则 get
将返回 struct
类型的数组,数组中的每个结构体对应于 H
中的一个对象。每个结构体中的每个字段对应于由 H
的类定义的一个属性。每个字段的值就是对应属性的值。
SV = get(H);
如果不指定输出变量,则 H
必须为标量。
有关示例,请参阅对句柄数组使用 get。
set 方法语法
set
方法为具有句柄 H
的对象的指定属性赋予指定值。如果 H
是句柄数组,MATLAB 会为数组 H
中每个对象的属性赋值。
set(H,'PropertyName',PropertyValue)
您可以将属性名称的元胞数组和属性值的元胞数组传递给 set
:
props = {'PropertyName1','PropertyName2'}; vals = {Property1Value,Property2Value}; set(H,props,vals)
如果 length(H)
大于 1,属性值元胞数组 (vals
) 可以为每个对象中的每个属性设置值。例如,假设 length(H)
是 2(两个对象句柄)。您要为每个对象赋予两个属性值:
props = {'PropertyName1','PropertyName2'}; vals = {Property11Value,Property12Value;Property21Value,Property22Value}; set(H,props,vals))
上述语句等效于以下两个语句:
set(H(1),'PropertyName1',Property11Value,'PropertyName2',Property12Value) set(H(2),'PropertyName1',Property21Value,'PropertyName2',Property22Value)
如果指定标量句柄,但没有属性名称,则 set
将返回 struct
,H
的类中的每个属性都对应该结构体中的一个字段。每个字段包含一个空元胞数组。
SV = set(h);
提示
可以在一次 set
调用中使用属性名称/属性值元胞数组、结构体数组(字段名称作为属性名称,字段值作为属性值)和元胞数组的任意组合。
派生自 matlab.mixin.SetGet 的类
此示例类定义一个 set/get 接口,并演示继承的方法的行为:
classdef LineType < matlab.mixin.SetGet properties Style = '-' Marker = 'o' end properties (SetAccess = protected) Units = 'points' end methods function obj = LineType(s,m) if nargin > 0 obj.Style = s; obj.Marker = m; end end function set.Style(obj,val) if ~(strcmpi(val,'-') ||... strcmpi(val,'--') ||... strcmpi(val,'..')) error('Invalid line style ') end obj.Style = val; end function set.Marker(obj,val) if ~isstrprop(val,'graphic') error('Marker must be a visible character') end obj.Marker = val; end end end
创建类的实例并保存其句柄:
h = LineType('--','*');
使用继承的 get
方法查询对象属性的值:
get(h,'Marker')
ans = '*'
使用继承的 set
方法设置属性的值:
set(h,'Marker','Q')
用 set 和 get 调用属性访问方法
使用 set
和 get
方法时,MATLAB 会调用属性访问方法(LineType
类中的 set.Style
或 set.Marker
)。
set(h,'Style','-.-')
Error using LineType/set.Style (line 20) Invalid line style
有关属性访问方法的详细信息,请参阅 属性 get 和 set 方法
列出所有属性
使用 get
返回包含对象属性及其当前值的 struct
:
h = LineType('--','*'); SV = get(h)
SV = struct with fields: Style: '--' Marker: '*' Units: 'points'
使用 set
返回包含具有 public
SetAccess
的属性的 struct
:
S = set(h)
S = struct with fields: Style: {} Marker: {}
LineType
类使用 SetAccess = protected
定义 Units
属性。因此,S = set(h)
不为 S
中的 Units
创建字段。
set
无法返回具有非公共 set 访问权限的属性的可能值。
对句柄数组使用 get
假设您创建了一个 LineType
对象数组:
H = [LineType('..','z'),LineType('--','q')]
H = 1x2 LineType with properties: Style Marker Units
当 H
是句柄数组时,get
返回属性值的 (length(H)
×1) 元胞数组:
CV = get(H,'Style')
CV = 2×1 cell array {'..'} {'--'}
当 H
是句柄数组而您没有指定属性名称时,get
返回 struct
数组,其中的字段具有与属性名称对应的名称。当 H
不是标量时,将 get
的输出赋给变量。
SV = get(H)
SV = 2x1 struct array with fields: Style Marker Units
从 SV
结构体数组的第二个数组元素中获取 Marker
属性的值:
SV(2).Marker
ans = 'q'
句柄、名称和值的数组
您可以将句柄数组、属性名称元胞数组和属性值元胞数组传递给 set
。对于 H
中的每个对象,属性值元胞数组必须有一行与之对应的属性值。对于属性名称数组中的每个属性,上述每行都必须有一个与之对应的值:
H = [LineType('..','z'),LineType('--','q')]; set(H,{'Style','Marker'},{'..','o';'--','x'})
对 set
的此调用的结果是:
H(1)
ans = LineType with properties: Style: '..' Marker: 'o' Units: 'points
H(2)
ans = LineType with properties: Style: '--' Marker: 'x' Units: 'points'
自定义属性列表
通过在子类中重新定义以下方法,自定义属性列表的显示方式:
为属性名称的部分匹配设置优先级
从 matlab.mixin.SetGet
派生的类可以使用 PartialMatchPriority
属性特性为部分名称匹配指定相对优先级。当解析匹配多个属性名称的不完整且不区分大小写的文本字符串时,MATLAB 应用此属性。
当不精确的名称字符串不具有多义性时,继承的 set
和 get
方法可以解析不精确的属性名称。当部分属性名称因与多个属性匹配而具有多义性时,PartialMatchPriority
属性值可以确定 MATLAB 与哪个属性匹配。
默认优先级等效于 PartialMatchPriority = 1
。要降低属性的相对优先级,请将 PartialMatchPriority
设置为 2 或更大的正整数值。随着 PartialMatchPriority
值的增加,属性的优先权会降低。
例如,在此类中,Verbosity
属性的名称匹配优先级高于 Version
属性。
classdef MyClass < matlab.mixin.SetGet properties Verbosity end properties (PartialMatchPriority = 2) Version end end
使用可能具有多义性的不精确名称 Ver
调用 set
方法会设置 Verbosity
属性,因为其相对优先级较高。如果不设置 PartialMatchPriority
属性,具有多义性的名称将导致错误。
a = MyClass;
set(a,"Ver",10)
disp(a)
MyClass with properties: Verbosity: 10 Version: []
相同的名称选择机制也适用于 get
方法。
v = get(a,"Ver")
v = 10
大小写和名称匹配
大小写不匹配的全名匹配优先于具有较高优先级属性的部分匹配。例如,此类定义优先级为 1(默认值)的 BaseLine
属性和优先级为 2(低于 1)的 Base
属性。
classdef MyClass < matlab.mixin.SetGet properties BaseLine end properties (PartialMatchPriority = 2) Base end end
用字符串 base
调用 set
方法会设置 Base
属性。BaseLine
具有更高的优先级,但只是大小写不一样的全名匹配更优先。
a = MyClass;
set(a,"base",-2)
disp(a)
MyClass with properties: BaseLine: [] Base: -2
添加新属性时减少不兼容问题
您可以使用 PartialMatchPriority
属性来避免在添加新属性时引入代码不兼容问题。例如,以下类使 set
和 get
方法能够使用字符串 Dis
引用 Distance
属性,因为 DiscreteSamples
属性的优先级较低。
classdef Planet < matlab.mixin.SetGet % Version 1.0 properties Distance end properties(PartialMatchPriority = 2) DiscreteSamples end end
该类的 2.0 版引入了名为 Discontinuities
的属性。为了防止在现有代码中导致具有多义性的部分属性名称,请使用 PartialMatchPriority
将 Discontinuities
的优先级设置为低于以前存在的属性的优先级。
classdef Planet < matlab.mixin.SetGet % Version 2.0 properties Diameter; NumMoons = 0 ApparentMagnitude; DistanceFromSun; end properties(PartialMatchPriority = 2) DiscreteSamples; end properties(PartialMatchPriority = 3) Discontinuities = false; end end
对于 Planet
类的 1.0 版,对 set
方法的以下调用并不具有多义性。
p = Planet;
set(p,"Disc",true)
然而,随着 Discontinuities
属性的引入,字符串 Disc
将具有多义性。通过降低 Discontinuities
属性的优先级,字符串 Disc
将继续匹配 DiscreteSamples
属性。
注意
在编写可重用代码时,使用完整的、区分大小写的属性名称可以避免多义性,防止与后续软件版本不兼容,并生成更可读的代码。
另请参阅
set
| get
| matlab.mixin.SetGet
| matlab.mixin.SetGetExactNames