Main Content

クラス定義内の式の評価

式を使用する理由

クラス定義で使用できる式は、評価結果が単一の配列になる任意の 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 メソッドは呼び出されません (これらの特別なメソッドの詳細については、プロパティの get メソッドおよび 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 属性の値として、matlab.metadata.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

オブジェクト bObjProp プロパティは、オブジェクト aObjProp プロパティと同じオブジェクトのハンドルを含んでいます。TimeProp プロパティの値は、このオブジェクトでも変化します。

a.ObjProp.TimeProp
ans =

08-Oct-2003 17:47:34

関連するトピック