Main Content

クラスによる構造化データの表現

データ構造体としてのオブジェクト

この例は、特定の構造をもつデータを保存するクラスを定義します。データ保存に一貫性のある構造を使用すると、そのデータを扱う関数の作成がより簡単になります。MATLAB®struct のフィールド名でデータ要素を表しておくと、データの整理に便利です。しかしクラスでは、データ ストレージ (プロパティ) とそのデータに対し実行できる操作 (メソッド) の両方を定義することが可能です。この例では、これらの利点について説明します。

例の背景

この例では、データは引張応力および歪みの測定値を表します。これらのデータは、さまざまな材料の弾性率の計算に使用されます。簡単に言えば、応力は材料に加えられる力であり、歪みはその結果の変形です。それらの比は、材料の特性を特徴付けます。この方法は、過程を単純化し過ぎですが、この例では十分です。

データの構造

次の表は、データの構造について説明したものです。

データ

説明

Material

試験する材料の種類を表す char ベクトル

SampleNumber

特定の試験サンプル数

Stress

テスト中にサンプルに加えられる応力を表す数値のベクトル。

Strain

加えられた応力の値に対応する歪みを表す数値のベクトル。

Modulus

応力と歪みのデータから計算される、テスト材料の弾性率を定義する数値

TensileData クラス

この例ではクラスの単純な実装から始め、この実装をさらに発展させて、機能がクラスの有用性をどのように高めるかを示します。

このクラスの最初のバージョンでは、データ ストレージのみが提供されます。クラスは必要な各データ要素のプロパティを定義します。

classdef TensileData
   properties
      Material
      SampleNumber
      Stress
      Strain
      Modulus
   end
end

インスタンスの作成とデータの代入

次のステートメントは TensileData オブジェクトを作成してデータを代入します。

td = TensileData;
td.Material = 'Carbon Steel';
td.SampleNumber = 001;
td.Stress = [2e4 4e4 6e4 8e4];
td.Strain = [.12 .20 .31 .40];
td.Modulus = mean(td.Stress./td.Strain);

クラスと構造体の利点の比較

TensileData オブジェクト (上記ステートメントの td) は、他の MATLAB 構造体とほぼ同様に取り扱います。ただし、一般的なデータ構造体を使用する場合と比較すると特化したデータ構造体をクラスとして定義する方が、以下の MATLAB struct のように利点があります。

  • フィールド名のスペルを誤ると、エラーが表示されます。たとえば、以下を入力します。

    td.Modulus = ...
    

    この場合、単純に構造体へフィールドが追加されます。ただし、tdTensileData クラスのインスタンスの場合は、エラーが返されます。

  • クラスは再利用が容易です。いったんユーザーがクラスを定義すると、新しい特性を追加するサブクラスを使用して容易に拡張できます。

  • クラスは識別が容易です。クラスは名前をもつので、関数 whos, class やワークスペース ブラウザーを使用して、オブジェクトを識別できます。クラス名が意味のある名前であると、履歴を参照しやすくなります。

  • クラスまたは値を含む、フィールドに値が割り当てられると、クラスは個々のフィールドを有効にできます。

  • クラスはフィールドへのアクセスを制限できます。たとえば、特定のフィールドの読み込みは許可し、変更は不可能とすることができます。

プロパティ値を特定値に制限

プロパティの set アクセス メソッドを定義して、プロパティを特定の値に制限します。MATLAB はプロパティに値を設定するたびに set アクセス メソッドを呼び出します。

Material プロパティの関数 set

Material プロパティの set メソッドは、プロパティに代入可能な string を、aluminumstainless steelcarbon steel のいずれかに制限します。

methods ブロックにこの関数定義を追加します。

classdef TensileData
   properties
      Material
      SampleNumber
      Stress
      Strain
      Modulus
   end
   methods
      function obj = set.Material(obj,material)
         if (strcmpi(material,'aluminum') ||...
               strcmpi(material,'stainless steel') ||...
               strcmpi(material,'carbon steel'))
            obj.Material = material;
         else
            error('Invalid Material')
         end
      end
   end
end

Material プロパティを設定しようとすると、MATLAB はプロパティ値を設定する前に set.Material メソッドを呼び出します。

値が許可される値と一致すると、関数はプロパティをその値に設定します。set メソッド内のコードは、プロパティの set メソッドの再帰的な呼び出しを回避するため、プロパティに直接アクセスできます。

以下に例を示します。

td = TensileData;
td.Material = 'brass';
Error using TensileData/set.Material
Invalid Material

コンストラクターを使用したインターフェイスの単純化

次のようなコンストラクターを追加することによって、TensileData クラスのインターフェイスを単純化します。

  • コンストラクターへの引数として、データを渡すことができる

  • プロパティ値の割り当て

コンストラクターは、クラスと同じ名前をもつメソッドです。

methods
   function td = TensileData(material,samplenum,stress,strain)
      if nargin > 0
         td.Material = material;
         td.SampleNumber = samplenum;
         td.Stress = stress;
         td.Strain = strain;
      end
   end 
end

次のステートメントを使用して、データが完全に設定された TensileData オブジェクトを作成します。

td = TensileData('carbon steel',1,...
      [2e4 4e4 6e4 8e4],...
      [.12 .20 .31 .40]);

オンデマンドのデータ計算

あるプロパティの値が他のプロパティの値に依存している場合は、そのプロパティを Dependent 属性を使用して定義します。MATLAB は依存プロパティの値を保存しません。依存プロパティの get メソッドは、プロパティがアクセスされるとそのプロパティ値を確定します。アクセスは、オブジェクト プロパティを表示するときに、または明示的なクエリの結果として発生する場合があります。

弾性率の計算

TensileData オブジェクトは Modulus プロパティの値を保存しません。コンストラクターには、Modulus プロパティの値に対する入力引数がありません。Modulus の値は、

  • StressStrain プロパティの値から計算されます

  • Stress プロパティまたは Strain プロパティの値が変化した場合は、変更しなければなりません

したがって、Modulus プロパティの値は、値が要求された場合にのみ計算するのが適切です。プロパティの get アクセス メソッドを使用して Modulus の値を計算します。

Modulus プロパティの get メソッド

Modulus プロパティは StressStrain に依存するので、その Dependent 属性は true です。Modulus プロパティを別個の properties ブロックに配置し、Dependent 属性を設定します。

get.Modulus メソッドは Modulus プロパティの値を算出して返します。

properties (Dependent)
   Modulus
end

既定の属性のみを使用して、methods ブロックでプロパティの get メソッドを定義します。

methods
   function modulus = get.Modulus(obj)
      ind = find(obj.Strain > 0);
      modulus = mean(obj.Stress(ind)./obj.Strain(ind));
   end
end

このメソッドでは、分母データのゼロを除いた後に、応力データと歪みデータの平均比が計算されます。

プロパティがクエリされると、MATLAB は get.Modulus メソッドを呼び出します。以下に例を示します。

td = TensileData('carbon steel',1,...
      [2e4 4e4 6e4 8e4],...
      [.12 .20 .31 .40]);
td.Modulus
ans =
  1.9005e+005

Modulus プロパティの set メソッド

Dependent プロパティの値を設定するには、クラスにプロパティの set メソッドを実装しなければなりません。Modulus プロパティの明示的な設定を許可する必要はありません。しかし、set メソッドを使うと、カスタマイズしたエラー メッセージを提供できるようになります。Modulus の set メソッドは、プロパティの現在の値を参照してエラーを返します。

methods
   function obj = set.Modulus(obj,~)
      fprintf('%s%d\n','Modulus is: ',obj.Modulus)
      error('You cannot set the Modulus property');
   end
end

TensileData オブジェクトの表示

TensileData クラスは disp メソッドをオーバーロードします。このメソッドはコマンド ウィンドウにおけるオブジェクトの表示を制御します。

disp メソッドは、MaterialSampleNumber および Modulus プロパティの値を表示します。Stress および Strain プロパティのデータは表示しません。これらのプロパティには、コマンド ウィンドウでは閲覧しにくい生データが含まれています。

disp メソッドは、fprintf を使用して、コマンド ウィンドウに書式付きテキストを表示します。

methods
   function disp(td)
      fprintf(1,...
         'Material: %s\nSample Number: %g\nModulus: %1.5g\n',...
         td.Material,td.SampleNumber,td.Modulus);
   end 
end

応力と歪みをプロットするメソッド

加えられた張力の範囲での材料の動作を知るには、応力/歪みのデータのグラフ表示が役立ちます。TensileData クラスは MATLAB 関数 plot をオーバーロードします。

plot メソッドは、応力と歪みのデータの線形グラフを作成し、タイトルと座標軸のラベルを追加して、張力データ記録の標準化されたグラフを作成します。

methods
   function plot(td,varargin)
      plot(td.Strain,td.Stress,varargin{:})
      title(['Stress/Strain plot for Sample',...
         num2str(td.SampleNumber)])
      ylabel('Stress (psi)')
      xlabel('Strain %')
   end 
end

このメソッドの 1 番目の引数は、データを含む TensileData オブジェクトです。

このメソッドは、引数の可変リスト (varargin) を組み込みの関数 plot に直接渡します。TensileDataplot メソッドを使うと、ライン指定子引数またはプロパティ名と値のペアを渡すことができます。

以下に例を示します。

td = TensileData('carbon steel',1,...
      [2e4 4e4 6e4 8e4],[.12 .20 .31 .40]);
plot(td,'-+b','LineWidth',2)

Stress graphed as function of strain

TensileData クラスの概要

コード例説明
classdef TensileData

値クラスによりオブジェクトの独立したコピーが可能になります。詳細は、ハンドル クラスと値クラスの比較を参照してください。

   properties
      Material
      SampleNumber
      Stress
      Strain
   end

データの構造を参照してください。

   properties (Dependent)
      Modulus
   end 

クエリされると Modulus を計算します。このコードの詳細については、オンデマンドのデータ計算を参照してください。

一般情報は、依存プロパティの get メソッドおよび set メソッドを参照してください。

   methods

メソッドについての一般情報は、通常のメソッドを参照してください。

   function td = TensileData(material,samplenum,...
      stress,strain)
      if nargin > 0
         td.Material = material;
         td.SampleNumber = samplenum;
         td.Stress = stress;
         td.Strain = strain;
      end
   end

このコードの詳細については、コンストラクターを使用したインターフェイスの単純化を参照してください。

コンストラクターについての一般情報は、クラス コンストラクター メソッドを参照してください。

   function obj = set.Material(obj,material)
      if (strcmpi(material,'aluminum') ||...
         strcmpi(material,'stainless steel') ||...
         strcmpi(material,'carbon steel'))
         obj.Material = material;
      else
         error('Invalid Material')
      end
   end

Material プロパティが取り得る値を制限します。

このコードについての詳細は、プロパティ値を特定値に制限を参照してください。

プロパティの set メソッドについての一般情報は、プロパティの get メソッドおよび set メソッドを参照してください。

   function m = get.Modulus(obj)
      ind = find(obj.Strain > 0); 
      m = mean(obj.Stress(ind)./obj.Strain(ind)); 
   end 

クエリされると Modulus プロパティを計算します。

このコードについての詳細は、Modulus プロパティの get メソッドを参照してください。

プロパティの get メソッドについての一般情報は、プロパティの get メソッドおよび set メソッドを参照してください。

   function obj = set.Modulus(obj,~)
      fprintf('%s%d\n','Modulus is: ',obj.Modulus)
      error('You cannot set Modulus property'); 
   end 

Dependent 属性をもつ Modulus プロパティに set メソッドを追加します。このコードの詳細については、Modulus プロパティの set メソッドを参照してください。

プロパティの set メソッドについての一般情報は、プロパティの get メソッドおよび set メソッドを参照してください。

   function disp(td)
      fprintf(1,'Material: %s\nSample Number: %g\nModulus: %1.5g\n',...
      td.Material,td.SampleNumber,td.Modulus)
   end 

disp メソッドをオーバーロードして、特定のプロパティを表示します。

このコードについての詳細は、TensileData オブジェクトの表示を参照してください。

disp のオーバーロードについての一般情報は、関数 disp のオーバーロードを参照してください。

   function plot(td,varargin)
      plot(td.Strain,td.Stress,varargin{:})
      title(['Stress/Strain plot for Sample',...
         num2str(td.SampleNumber)])
      ylabel('Stress (psi)')
      xlabel('Strain %')
   end 

関数 plot をオーバーロードして、TensileData オブジェクトを受け入れ、応力と歪みの関係をグラフ化します。

応力と歪みをプロットするメソッド

   end
end

methods および classdefend ステートメント。

 クラス コードの拡張

関連するトピック