Main Content

ハンドル互換クラスの定義方法

ハンドル互換とは

クラスは以下の場合にハンドル互換です。

  • ハンドル クラスである

  • 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

関連するトピック