ハンドル互換クラスの定義方法
ハンドル互換とは
クラスは以下の場合にハンドル互換です。
ハンドル クラスである
HandleCompatible
属性がtrue
に設定されている
HandleCompatible
クラス属性は、スーパークラスのセットを指定するときにハンドル クラスで結合できるクラスを識別します。
ハンドル互換性は、抽象スーパークラスを定義する場合に高い柔軟性を実現します。たとえば、ハンドルと値の両方のサブクラスをサポートするスーパークラスを使用する場合は、ハンドル互換性により、クラスのハンドル バージョンと非ハンドル バージョンの両方を定義する必要がなくなります。
ハンドル互換クラス
この例では、Utility
クラスがプロパティ値をそれぞれのクラス定義で定義される既定値にリセットするメソッドを定義します。この機能はハンドル サブクラスおよび値サブクラスの両方にとって有用です。
classdef (HandleCompatible) Utility methods function obj = resetDefaults(obj) mc = metaclass(obj); mp = mc.PropertyList; for k=1:length(mp) if mp(k).HasDefault && ~strcmp(mp(k).SetAccess,'private') obj.(mp(k).Name) = mp(k).DefaultValue; end end end end end
Utility
クラスはハンドル互換です。したがって、このクラスを使用して、ハンドル クラスか値クラスのいずれかとなるクラスを導き出すことができます。メタデータ クラスの使用方法の詳細は、クラス イントロスペクションおよびメタデータを参照してください。
変更されたオブジェクトを返す
Utility
クラスによって定義される resetDefaults
メソッドは、オブジェクトを変更して返します。resetDefaults
を値オブジェクトと共に呼び出した場合、メソッドは変更されたオブジェクトを返さなければなりません。ハンドル互換スーパークラスにハンドル オブジェクトと値オブジェクトの両方と機能するメソッドを実装することが重要です。ハンドル オブジェクトと値オブジェクトの変更の詳細は、オブジェクトの変更を参照してください。
Utility
クラスをサブクラス化する値クラスの動作を考えてみましょう。PropertyDefaults
クラスは 3 つのプロパティを定義し、そのすべてが既定値をもちます。
classdef PropertyDefaults < Utility properties p1 = datestr(rem(now,1)) % Current time p2 = 'red' % Character vector p3 = pi/2 % Result of division operation end end
PropertyDefaults
オブジェクトを作成します。MATLAB® は、クラスが最初に読み込まれるときに既定のプロパティ値として代入される式を評価します。MATLAB は、現在の MATLAB セッションでこのクラスのインスタンスが作成されるときに、必ずこれらの同じ既定値を使用します。
pd = PropertyDefaults
pd = PropertyDefaults with properties: p1: ' 4:42 PM' p2: 'red' p3: 1.5708
既定値と異なる新しい値を割り当てます。
pd.p1 = datestr(rem(now,1));
pd.p2 = 'green';
pd.p3 = pi/4;
すべての pd
オブジェクト プロパティ値にクラスによって本来定義された既定値とは異なる値が含まれるようになりました。
pd
pd = PropertyDefaults with properties: p1: ' 4:45 PM' p2: 'green' p3: 0.7854
Utility
クラスから継承される resetDefaults
メソッドを呼び出します。PropertyDefaults
クラスはハンドル クラスではないため、変更されたオブジェクトを返します。
pd = pd.resetDefaults
pd = PropertyDefaults with properties: p1: ' 4:54 PM' p2: 'red' p3: 1.5708
PropertyDefaults
クラスがハンドル クラスであった場合、resetDefaults
メソッドで返されるオブジェクトを保存する必要はありません。Utility
のようなハンドル互換クラスを設計するには、すべてのメソッドが両方の種類のクラスで機能するよう確認します。
ハンドル互換クラスのサブクラス化
ハンドル互換性規則 で説明した規則に従って、ハンドル スーパークラスをハンドル互換スーパークラスと結合する場合、結果はハンドル サブクラスとなり、ハンドル互換となります。
ただし、ハンドル互換クラスをサブクラス化しても、必ずしもサブクラスがハンドル互換にはなりません。次の 2 つの場合を考えてみましょう。これらは 2 つの考えられる結果を示します。
非ハンドル ユーティリティ クラスをハンドル クラスと結合する
ハンドル クラスおよびハンドル互換クラスで説明したハンドル互換 Utility
クラスをサブクラス化するクラスを定義します。HPropertyDefaults
クラスには、次の特性があります。
これは
handle
から派生するためハンドル クラスである。ハンドル クラスは定義によりハンドル互換であるため、このクラスのスーパークラスはすべてハンドル互換である。
classdef HPropertyDefaults < handle & Utility properties GraphPrim = line Width = 1.5 Color = 'black' end end
HPropertyDefaults
クラスはハンドル互換です。
hpd = HPropertyDefaults; mc = metaclass(hpd); mc.HandleCompatible
ans = 1
ハンドル互換クラスの非ハンドル サブクラス
ハンドル互換でない値クラスとハンドル互換クラスの両方をサブクラス化する場合、サブクラスは非ハンドル互換の値クラスになります。ValueSub
クラスは、以下のようになります。
値クラスです (
handle
から派生しません)。この値クラスのスーパークラスの 1 つはハンドル互換です (
Utility
クラス)。
classdef ValueSub < MException & Utility methods function obj = ValueSub(str1,str2) obj = obj@MException(str1,str2); end end end
ValueSub
クラスは、ハンドル互換でない値クラスです。これは、MException
クラスが HandleCompatible
属性を true
として定義しないためです。
hv = ValueSub('MATLAB:narginchk:notEnoughInputs',... 'Not enough input arguments.'); mc = metaclass(hv); mc.HandleCompatible
ans = 0