クラス コンストラクター メソッド
クラス コンストラクター メソッドの目的
コンストラクター メソッドは、そのクラスのインスタンスを作成する特殊な関数です。一般に、コンストラクター メソッドは、プロパティに保存されるデータを割り当て、初期化されたオブジェクトを返すために、入力引数を受け入れます。
基本的な例については、単純なクラスの作成を参照してください。
クラス コンストラクターを明示的に定義しない MATLAB® クラスには既定のコンストラクター メソッドがあります。このメソッドは、入力引数なしで作成されたクラスのオブジェクトを返します。クラスは、既定のコンストラクターをオーバーライドするコンストラクター メソッドを定義できます。明示的に定義されたコンストラクターは、入力引数の受け入れ、プロパティ値の初期化、その他のメソッドの呼び出し、クラスのオブジェクトを作成するために必要なその他の操作を行うことができます。
コンストラクター メソッドの基本構造
コンストラクター メソッドは、3 つの基本的な部分から構成されます。
初期化前 — スーパークラス コンストラクターの引数を求めます。
オブジェクトの初期化 — スーパークラスのコンストラクターを呼び出します。
初期化後 — オブジェクトへの参照と割り当て、クラス メソッドの呼び出し、関数へのオブジェクトの渡しなどを含む、サブクラスに関連する操作を実行します。
次のコードは、各セクションで実行される基本の操作を説明します。
classdef ConstructorDesign < BaseClass1 properties ComputedValue end methods function obj = ConstructorDesign(a,b,c) %% Pre Initialization %% % Any code not using output argument (obj) if nargin == 0 % Provide values for superclass constructor % and initialize other inputs a = someDefaultValue; args{1} = someDefaultValue; args{2} = someDefaultValue; else % When nargin ~= 0, assign to cell array, % which is passed to supclass constructor args{1} = b; args{2} = c; end compvalue = myClass.staticMethod(a); %% Object Initialization %% % Call superclass constructor before accessing object % You cannot conditionalize this statement obj = obj@BaseClass1(args{:}); %% Post Initialization %% % Any code, including access to object obj.classMethod(arg); obj.ComputedValue = compvalue; ... end ... end ... end
任意の関数のようにコンストラクターを呼び出し、引数を渡してクラスのオブジェクトを返します。
obj = ConstructorDesign(a,b,c);
コンストラクターのガイドライン
コンストラクターはクラスと同じ名前をもちます。
コンストラクターは複数の引数を返すことができますが、最初の出力は作成されたオブジェクトでなければなりません。
出力引数を割り当てない場合、コンストラクター内のオブジェクト変数をクリアできます (出力オブジェクトの抑制を参照)。
クラス コンストラクターを作成する場合は、入力引数なしで呼び出せるようにします。入力引数なしでコンストラクターを呼び出す条件を参照してください。
コンストラクターがスーパークラス コンストラクターを明示的に呼び出す場合、この呼び出しは構築されるオブジェクトへの他の参照より前に行わなければならず、また、
return
ステートメントの後に行うことはできません。スーパークラス コンストラクターを、条件付きで呼び出すことはできません。スーパークラスのコンストラクターの呼び出しは、ループ、条件文、スイッチ、try/catch、入れ子関数内に置くことはできません。詳細は、スーパークラス コンストラクターの条件なしの呼び出しを参照してください。
既定のコンストラクター
クラスでコンストラクターが定義されていない場合、MATLAB は引数を取らずにスカラー オブジェクトを返す既定のコンストラクターを提供します。このオブジェクトのプロパティは既定値に初期化されています。また、MATLAB が提供する既定のコンストラクターは、引数なしで、または既定のサブクラス コンストラクターに渡される任意の引数を指定してあらゆるスーパークラス コンストラクターを呼び出します。
サブクラスがコンストラクターを定義しない場合は、既定のコンストラクターはその入力を直接のスーパークラス コンストラクターに渡します。この動作は、サブクラスでコンストラクターを定義する必要はないが、スーパークラス コンストラクターが入力引数を必要とする場合に役立ちます。
コンストラクターを定義する場合
既定のコンストラクターでは実行できないオブジェクトの初期化を実行するコンストラクター メソッドを定義します。たとえば、クラスのオブジェクトを作成する場合に、以下が必要になります。
入力引数
クラスの各インスタンスについて、プロパティ値などのオブジェクトの状態の初期化
サブクラス コンストラクターにより決定される値を使用したスーパークラス コンストラクターの呼び出し
関連情報
列挙の作成に固有の情報については、列挙クラス コンストラクターの呼び出しシーケンスを参照してください。
コンストラクターでのオブジェクト配列の作成の詳細については、オブジェクト配列の作成と初期化を参照してください。
作成されているクラスがサブクラスである場合、MATLAB は、オブジェクトを初期化するために各スーパークラスのコンストラクターを呼び出します。スーパークラス コンストラクターを間接的に呼び出すときには、引数なしで行われます。スーパークラス コンストラクターが引数を必要とする場合、サブクラス コンストラクターから明示的に呼び出します。コンストラクターを呼び出す順序の制御を参照してください。
コンストラクターでのオブジェクトの初期化
コンストラクター メソッドは、初期化されたオブジェクトを、出力引数として返します。出力引数は、コードの最初の行を実行する前に、コンストラクターが実行するときに作成されます。
たとえば、次のコンストラクターでは、オブジェクト obj
が MyClass
のインスタンスに割り当てられているので、最初のステートメントとしてオブジェクトのプロパティ A
の値を割り当てることができます。
function obj = MyClass(a,b,c) obj.A = a; ... end
オブジェクトは既に初期化されているので、コンストラクターから他のクラス メソッドを呼び出すことができます。
コンストラクターは、プロパティが既定値をもつオブジェクトも作成します。既定値は、([]
) またはプロパティ定義ブロックで指定された既定値のいずれかです。
たとえば、このコンストラクターは入力引数の演算を行い Value
プロパティの値に代入します。
function obj = MyClass(a,b,c) obj.Value = (a + b) / c; ... end
コンストラクターのオブジェクトの参照
プロパティに値を代入するなどしてオブジェクトを初期化するときには、コンストラクター内でオブジェクトを参照するために、出力引数の名前を使用します。たとえば、以下のコードにおいて出力引数は obj
であり、このオブジェクトは obj
として参照されます。
% obj is the object being constructed function obj = MyClass(arg) obj.property1 = arg*10; obj.method1; ... end
既定のプロパティ値の定義についての詳細は、既定値をもつプロパティの定義を参照してください。
名前と値の引数を使用したプロパティの設定
オブジェクトを初期化するときに、プロパティ値を名前と値の引数として渡せるようにするには、構文 structName
.?ClassName
を使用します。たとえば、NameValueClass
コンストラクターは、渡されたすべての引数を構造体 opts
に集約し、for
ループを使用してプロパティ値を設定します。
classdef NameValueClass properties Property1 Property2 end properties (SetAccess=immutable) ImmProperty end methods function obj = NameValueClass(opts) arguments opts.?NameValueClass end for prop = string(fieldnames(opts))' obj.(prop) = opts.(prop); end end end end
クラス コンストラクターを呼び出し、名前と値の構文を使用して ImmProperty
を設定します。
x = NameValueClass(ImmProperty=1)
x = NameValueClass with properties: Property1: [] Property2: [] ImmProperty: 1
クラス プロパティを関数で名前と値の引数として使用する方法の詳細については、クラス プロパティからの名前と値の引数を参照してください。
R2024a より前: 構文 structName
.?ClassName
は、不変プロパティでは機能しませんでした。以前のリリースでこの手法を使用するには、不変プロパティと一致する名前と値の引数を別の行で定義します。たとえば、NameValueClass
では次のようになります。arguments
opts.ImmProperty
opts.?NameValueClass
end
入力引数なしでコンストラクターを呼び出す条件
入力引数なしでコンストラクターを呼び出すことが必要な場合があります。
オブジェクトをワークスペースに読み込むとき、クラスの
ConstructOnLoad
属性がtrue
に設定されると、関数load
は引数なしでクラス コンストラクターを呼び出します。値が指定されていない要素をもつオブジェクト配列を作成または拡張するとき、未指定の要素を埋めるために、クラス コンストラクターが引数なしで呼び出されます (たとえば
x(10,1) = MyClass(a,b,c);
)。この場合、コンストラクターが引数なしで 1 回呼び出され、この 1 つのオブジェクトのコピーを空の配列要素 (x(1:9,1)
) に与えます。
コンストラクターは、入力引数がないときには、既定のプロパティ値のみを使用してオブジェクトを作成します。上記 2 つのケースのいずれかが起こるときには、エラーを回避するために、クラス コンストラクターにゼロ引数のチェックを追加するのが適切です。
function obj = MyClass(a,b,c) if nargin > 0 obj.A = a; obj.B = b; obj.C = c; ... end end
スーパークラス コンストラクターを取り扱う方法については、コンストラクター メソッドの基本構造を参照してください。
サブクラス コンストラクター
サブクラス コンストラクターは、スーパークラス コンストラクターに引数を渡すためにスーパークラス コンストラクターを明示的に呼び出すことができます。サブクラス コンストラクターは、スーパークラス コンストラクターの呼び出しでこれらの引数を指定しなければならず、さらにコンストラクター出力引数を使用して、呼び出しを作成しなければなりません。構文は、以下のとおりです。
classdef MyClass < SuperClass methods function obj = MyClass(a,b,c,d) obj@SuperClass(a,b); ... end end end
サブクラス コンストラクターは、スーパークラス コンストラクターに対するすべての呼び出しを、そのオブジェクト (obj
) への他の参照の前に行わなければなりません。この制限には、プロパティ値の代入や通常のクラス メソッドの呼び出しが含まれます。また、サブクラス コンストラクターがスーパークラス コンストラクターを呼び出せるのは 1 回だけです。
指定されたスーパークラスのみの参照
classdef
がクラスをスーパークラスとして指定していない場合、コンストラクターが次の構文でスーパークラス コンストラクターを呼び出すことはできません。すなわち、サブクラス コンストラクターは classdef
行にリストされた直接のスーパークラス コンストラクターのみ呼び出すことができます。
classdef MyClass < SuperClass1 & SuperClass2
MATLAB は、呼び出されていないコンストラクターを classdef
行で指定された左から右の順序で呼び出します。MATLAB はこれらの呼び出しに引数を渡しません。
スーパークラス コンストラクターの条件なしの呼び出し
スーパークラス コンストラクターの呼び出しは無条件でなければなりません。特定のスーパークラスに対しては 1 回の呼び出ししかできません。プロパティ値の代入やクラス メソッドの呼び出しなどでオブジェクトを使用する前に、スーパークラス コンストラクターを呼び出してオブジェクトのスーパークラスの部分を初期化します。
何らかの条件に依存する複数の引数で複数のスーパークラス コンストラクターを呼び出すには、引数の cell 配列を作成し、コンストラクターの呼び出しを 1 回にします。
たとえば、Cube
クラス コンストラクターは、引数なしで Cube
コンストラクターが呼び出される場合、既定値を使ってスーパークラス Shape
コンストラクターを呼び出します。Cube
コンストラクターが 4 つの入力引数を指定して呼び出される場合は、upvector
および viewangle
をスーパークラス コンストラクターに渡します。
classdef Cube < Shape properties SideLength = 0 Color = [0 0 0] end methods function cubeObj = Cube(length,color,upvector,viewangle) % Assemble superclass constructor arguments if nargin == 0 super_args{1} = [0 0 1]; super_args{2} = 10; elseif nargin == 4 super_args{1} = upvector; super_args{2} = viewangle; else error('Wrong number of input arguments') end % Call superclass constructor cubeObj@Shape(super_args{:}); % Assign property values if provided if nargin > 0 cubeObj.SideLength = length; cubeObj.Color = color; end ... end ... end end
引数なしまたは複数の引数をもつスーパークラス
引数なしでスーパークラス コンストラクターを呼び出す構文をサポートする場合は、構文を明示的に提供します。
Cube
クラスの例の場合で考えます。この例では、Shape
スーパークラスと Cube
サブクラス内のすべてのプロパティ値は、クラス定義内で指定された既定値を取ります。この場合、スーパークラス コンストラクターまたはサブクラス コンストラクターに対し引数を一切指定せずに、Cube
のインスタンスを作成できます。
以下では、Cube
コンストラクターでこの動作をどのように実装できるかを示します。
methods function cubeObj = Cube(length,color,upvector,viewangle) % Assemble superclass constructor arguments if nargin == 0 super_args = {}; elseif nargin == 4 super_args{1} = upvector; super_args{2} = viewangle; else error('Wrong number of input arguments') end % Call superclass constructor cubeObj@Shape(super_args{:}); % Assign property values if provided if nargin > 0 cubeObj.SideLength = length; cubeObj.Color = color; end ... end end
サブクラスの詳細
サブクラスの作成の詳細は、サブクラス コンストラクターの設計を参照してください。
継承されたコンストラクターの暗黙的な呼び出し
MATLAB は、既定のサブクラス コンストラクターからスーパークラス コンストラクターへ引数を暗黙的に渡します。この動作により、スーパークラス コンストラクターへ引数を渡すためだけにサブクラスのコンストラクター メソッドを実装する必要がなくなります。
たとえば、次のクラス コンストラクターは 1 つの入力引数 (datetime
オブジェクト) を必要とし、コンストラクターはそれを CurrentDate
プロパティに割り当てます。
classdef BaseClassWithConstr properties CurrentDate datetime end methods function obj = BaseClassWithConstr(dt) obj.CurrentDate = dt; end end end
BaseClassWithConstr
のサブクラスを作成するが、そのサブクラスには明示的なコンストラクター メソッドが必要ないとします。
classdef SubclassDefaultConstr < BaseClassWithConstr ... end
スーパークラスの引数を指定して既定のコンストラクターを呼び出すことにより、SubclassDefaultConstr
のオブジェクトを作成できます。
obj = SubclassDefaultConstr(datetime);
サブクラス コンストラクターの詳細については、サブクラス コンストラクターと既定のコンストラクターを参照してください。
クラス作成中のエラー
ハンドル クラスでは、次の条件でエラーが発生すると MATLAB によって delete
メソッドが呼び出されます。
エラーが発生する前の部分で、コードにオブジェクトへの参照がある。
エラーが発生する前の部分で、コードに早期の
return
ステートメントがある。
MATLAB はそのオブジェクトに対する delete
メソッド、プロパティに含まれているオブジェクトに対する delete
メソッド、初期化された基底クラスに対する delete
メソッドを呼び出します。
どの時点でエラーが発生するかによって、MATLAB はオブジェクトが完全に作成される前にクラス デストラクターを呼び出すことができます。そのため、クラスの delete
メソッドは、すべてのプロパティに値があるとは限らない、部分的に作成されたオブジェクトでも動作できなければなりません。詳細については、部分的に作成されたオブジェクトの破棄のサポートを参照してください。
オブジェクトがどのように破棄されるかについての詳細は、ハンドル クラスのデストラクターを参照してください。
出力オブジェクトの抑制
コンストラクターの呼び出しで出力変数が割り当てられていない場合、変数 ans
へのクラス インスタンスの代入を抑制できます。この手法は、作成されたオブジェクトに付随するグラフィカル インターフェイス ウィンドウを作成するアプリで役立ちます。これらのアプリはオブジェクトを返す必要がありません。
nargout
を使用して、コンストラクターが出力引数と共に呼び出されたかどうかを判別します。たとえば、MyApp
クラスのクラス コンストラクターは、出力を割り当てずに呼び出された場合、オブジェクト変数 obj
をクリアします。
classdef MyApp methods function obj = MyApp ... if nargout == 0 clear obj end end ... end end
クラス コンストラクターがオブジェクトを返さない場合、MATLAB は matlab.metadata.Class
InstanceCreated
イベントをトリガーしません。