クラス定義内の式の評価
式を使用する理由
クラス定義で使用できる式は、評価結果が単一の配列になる任意の MATLAB® の有効なステートメントです。式を使用して、プロパティの既定値を定義したり、属性を指定したりできます。式は他の値から値を派生させるのに便利です。たとえば、2
π の完全精度値をもつ定数プロパティを定義するとします。式 2*pi
によって返された値をプロパティに代入することができます。MATLAB は、クラスを最初に読み込んだときに関数を評価します。
既定値と属性値をプロパティに代入する方法の詳細については、プロパティ値の初期化およびプロパティの属性を参照してください。
クラス定義内で式を使用する場所
次に、クラス定義で使用した式の例をいくつか示します。
classdef MyClass % Some attributes are set to logical values properties (Constant = true) CnstProp = 2*pi end properties % Static method of this class Prop1 = MyClass.setupAccount % Constant property from this class Prop2 = MyClass.CnstProp % Function that returns a value Prop3 = datestr(now) % A class constructor Prop4 = AccountManager end methods (Static) function accNum = setupAccount accNum = randi(9,[1,12]); end end end
MATLAB では、既定値の式の結果をプロパティに割り当てるときに、プロパティの set メソッドは呼び出されません (これらの特別なメソッドの詳細については、プロパティ の set メソッドを参照してください。)
MATLAB 型から派生した列挙は、式を使用して値を代入できます。
classdef FlowRate < int32 enumeration Low (10) Medium (FlowRate.Low*5) High (FlowRate.Low*10) end end
MATLAB は、列挙メンバーが最初にアクセスされたときに 1 回だけ、これらの式を評価します。
属性の指定における式
論理値 true
または false
の属性値については、クラス定義は式を使用して属性値を指定できます。たとえば、次の割り当てでは、R2014b より前の MATLAB のバージョン (verLessThan
) に対して MyClass
がシールされています (サブクラス化することはできません)。
classdef (Sealed = verLessThan('matlab','8.4')) MyClass
等式記号 (=
) の右辺の式は true
または false
に評価されなければなりません。この式では、クラス ファイルにある定義 (定数プロパティ、静的メソッド、ローカル関数など) はいずれも使用できません。
条件式を使用して属性値を設定することは可能ですが、この場合、外部の条件に基づいてクラス定義が変わることがあります。クラスの設計ではこの動作は必ず一致させてください。
メモ
AllowedSubclasses
および InferiorClasses
属性には、その値として meta.class
オブジェクトの cell 配列の明示的な指定が必要です。式を使用してこれらの値を返すことはできません。
既定のプロパティ値を指定する式
プロパティの定義では、変数を参照しない任意の式を使用して、プロパティの既定値を指定できます。たとえば次の VectorAngle
では、まず定数プロパティ (Rad2Deg
) を定義し、このプロパティを別のプロパティ (Angle
) の既定値を定義する式で使用しています。また既定値の式も、クラスで定義されている静的メソッド (getAngle
) を使用しています。
classdef VectorAngle properties (Constant) Rad2Deg = 180/pi end properties Angle = VectorAngle.Rad2Deg*VectorAngle.getAngle([1 0],[0 1]) end methods function obj = VectorAngle(vx,vy) obj.Angle = VectorAngle.getAngle(vx,vy); end end methods (Static) function r = getAngle(vx,vy) % Calculate angle between 2D vectors cr = vx(1)*vy(1) + vx(2)*vy(2)/sqrt(vx(1)^2 + vx(2)^2) * ... sqrt(vy(1)^2 + vy(2)^2); r = acos(cr); end end end
Angle
プロパティの既定値を定義するために、コンストラクターへの入力変数は使用できません。たとえば、Angle
プロパティの次の定義は有効ではありません。
properties Angle = VectorAngle.Rad2Deg*VectorAngle.getAngle(vx,vy) end
インスタンスを作成しようとすると、エラーが発生します。
a = VectorAngle([1,0],[0,1])
Error using VectorAngle Unable to update the class 'VectorAngle' because the new definition contains an error: Undefined function or variable 'vx'.
クラス メソッドにおける式
クラス メソッドにおける式は、他の関数と同じように実行されます。MATLAB は、メソッドが実行されるときに関数のワークスペース内で式を評価します。したがって、クラス メソッドで使用されている式は、クラス定義の一部とはみなされません。このため、この節では説明していません。
MATLAB による式の評価方法
MATLAB では、クラス定義内の式がワークスペースを使用せずに評価されます。したがって、これらの式ではどのような種類の変数も参照することはできません。
MATLAB では、クラス ファイルのコンテキスト内で式が評価されます。このため、これらの式では、MATLAB がクラスを初期化した時点でパス上に存在する任意の関数、静的メソッド、他のクラスの定数プロパティにアクセスできます。プロパティの既定値を定義している式は、それ自体のクラスに定義されている定数プロパティにアクセスできます。
MATLAB による式の評価
MATLAB は、クラスを初期化する場合にのみ、クラス定義内の式を評価します。初期化は、クラスがはじめて使用される前に行われます。
初期化後は、これらの式から返される値はクラス定義の一部となり、クラスのすべてのインスタンスで一定になります。クラスのすべてのインスタンスで式の最初の評価結果が使用され、再評価が行われることはありません。
クラスをクリアすると、MATLAB によってクラス定義の一部である式が再評価され、クラスが再初期化されます(変更済みクラスの自動更新を参照)。
ハンドル クラスと値クラスの式の評価
次の例では、値およびハンドル オブジェクトを既定値としてプロパティに割り当てたときに、どのように動作するかを示します。次のクラスがあるとします。
値クラスの式
ClassExp
クラスは ContClass
オブジェクトを含むプロパティをもちます。
classdef ContClass properties % Assign current date and time TimeProp = datestr(now) end end
classdef ClassExp properties ObjProp = ContClass end end
ClassExp
クラスをはじめて使用する場合、MATLAB により ContClass
クラスのインスタンスが作成されます。この時点で MATLAB は両方のクラスを初期化します。ClassExp
のすべてのインスタンスに、ContClass
の同じインスタンスのコピーが含まれています。
a = ClassExp; a.ObjProp.TimeProp
ans = 08-Oct-2003 17:16:08
ContClass
オブジェクトの TimeProp
プロパティは、MATLAB がクラスを初期化した日付と時刻を含みます。ClassExp
クラスの追加のインスタンスを作成しても、この日付文字列は変わりません。
b = ClassExp; b.ObjProp.TimeProp
ans = 08-Oct-2003 17:16:08
この例では、含まれるオブジェクトに値クラスを使用しているため、ClassExp
の各インスタンスには独自のオブジェクトのコピーがあります。たとえば、ClassExp
オブジェクトの b
に含まれるオブジェクトの TimeProp
プロパティの値を変更してみます。
b.ObjProp.TimeProp = datestr(now)
ans = 08-Oct-2003 17:22:49
オブジェクト a
に含まれるオブジェクトのコピーは変わりません。
a.ObjProp.TimeProp
ans = 08-Oct-2003 17:16:08
ハンドル クラスの式
次に、含まれるオブジェクトがハンドル オブジェクトの場合の動作を検討してみましょう。
classdef ContClass < handle properties TimeProp = datestr(now) end end
ClassExp
クラスのインスタンスを 2 つ作成すると、MATLAB が ContClass
を初期化したときにオブジェクトが作成されていることがわかります。MATLAB は、そのオブジェクトの "ハンドル" のコピーを ClassExp
クラスの各インスタンスで使用しています。したがって、ContClass
オブジェクトが 1 つあり、各 ClassExp
オブジェクトの ObjProp
プロパティはそのハンドルのコピーを含んでいることになります。
ClassExp
クラスのインスタンスを作成し、作成時間に注目します。
a = ClassExp; a.ObjProp.TimeProp
ans = 08-Oct-2003 17:46:01
ClassExp
クラスの 2 つ目のインスタンスを作成します。ObjProp
は、同じオブジェクトのハンドルを含んでいます。
b = ClassExp; b.ObjProp.TimeProp
ans = 08-Oct-2003 17:46:01
含まれるオブジェクト TimeProp
プロパティの値を再度代入します。
b.ObjProp.TimeProp = datestr(now); b.ObjProp.TimeProp
ans = 08-Oct-2003 17:47:34
オブジェクト b
の ObjProp
プロパティは、オブジェクト a
の ObjProp
プロパティと同じオブジェクトのハンドルを含んでいます。TimeProp
プロパティの値は、このオブジェクトでも変化します。
a.ObjProp.TimeProp
ans = 08-Oct-2003 17:47:34