クラスによる構造化データの表現
データ構造体としてのオブジェクト
この例は、特定の構造をもつデータを保存するクラスを定義します。データ保存に一貫性のある構造を使用すると、そのデータを扱う関数の作成がより簡単になります。MATLAB® の struct
のフィールド名でデータ要素を表しておくと、データの整理に便利です。しかしクラスでは、データ ストレージ (プロパティ) とそのデータに対し実行できる操作 (メソッド) の両方を定義することが可能です。この例では、これらの利点について説明します。
例の背景
この例では、データは引張応力および歪みの測定値を表します。これらのデータは、さまざまな材料の弾性率の計算に使用されます。簡単に言えば、応力は材料に加えられる力であり、歪みはその結果の変形です。それらの比は、材料の特性を特徴付けます。この方法は、過程を単純化し過ぎですが、この例では十分です。
データの構造
次の表は、データの構造について説明したものです。
データ | 説明 |
---|---|
| 試験する材料の種類を表す |
| 特定の試験サンプル数 |
| テスト中にサンプルに加えられる応力を表す数値のベクトル。 |
| 加えられた応力の値に対応する歪みを表す数値のベクトル。 |
| 応力と歪みのデータから計算される、テスト材料の弾性率を定義する数値 |
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 = ...
この場合、単純に構造体へフィールドが追加されます。ただし、
td
がTensileData
クラスのインスタンスの場合は、エラーが返されます。クラスは再利用が容易です。いったんユーザーがクラスを定義すると、新しい特性を追加するサブクラスを使用して容易に拡張できます。
クラスは識別が容易です。クラスは名前をもつので、関数
whos
,class
やワークスペース ブラウザーを使用して、オブジェクトを識別できます。クラス名が意味のある名前であると、履歴を参照しやすくなります。クラスまたは値を含む、フィールドに値が割り当てられると、クラスは個々のフィールドを有効にできます。
クラスはフィールドへのアクセスを制限できます。たとえば、特定のフィールドの読み込みは許可し、変更は不可能とすることができます。
プロパティ値を特定値に制限
プロパティの set アクセス メソッドを定義して、プロパティを特定の値に制限します。MATLAB はプロパティに値を設定するたびに set アクセス メソッドを呼び出します。
Material プロパティの関数 set
Material
プロパティの set メソッドは、プロパティに代入可能な string を、aluminum
、stainless steel
、carbon 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
の値は、
Stress
とStrain
プロパティの値から計算されますStress
プロパティまたはStrain
プロパティの値が変化した場合は、変更しなければなりません
したがって、Modulus
プロパティの値は、値が要求された場合にのみ計算するのが適切です。プロパティの get
アクセス メソッドを使用して Modulus
の値を計算します。
Modulus プロパティの get メソッド
Modulus
プロパティは Stress
と Strain
に依存するので、その 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
メソッドは、Material
、SampleNumber
および 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
に直接渡します。TensileData
の plot
メソッドを使うと、ライン指定子引数またはプロパティ名と値のペアを渡すことができます。
次に例を示します。
td = TensileData('carbon steel',1,... [2e4 4e4 6e4 8e4],[.12 .20 .31 .40]); plot(td,'-+b','LineWidth',2)
TensileData
クラスの概要
コード例 | 説明 |
---|---|
classdef TensileData | 値クラスによりオブジェクトの独立したコピーが可能になります。詳細は、ハンドル クラスと値クラスの比較を参照してください。 |
properties
Material
SampleNumber
Stress
Strain
end
| データの構造を参照してください。 |
properties (Dependent)
Modulus
end | クエリされると 一般情報は、依存プロパティの set および get メソッドを参照してください。 |
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 |
このコードについての詳細は、プロパティ値を特定値に制限を参照してください。 プロパティの set メソッドについての一般情報は、プロパティ の set メソッドを参照してください。 |
function m = get.Modulus(obj) ind = find(obj.Strain > 0); m = mean(obj.Stress(ind)./obj.Strain(ind)); end | クエリされると このコードについての詳細は、Modulus プロパティの get メソッドを参照してください。 プロパティの get メソッドについての一般情報は、プロパティ の set メソッドを参照してください。 |
function obj = set.Modulus(obj,~) fprintf('%s%d\n','Modulus is: ',obj.Modulus) error('You cannot set Modulus property'); end |
プロパティの set メソッドについての一般情報は、プロパティ の set メソッドを参照してください。 |
function disp(td) fprintf(1,'Material: %s\nSample Number: %g\nModulus: %1.5g\n',... td.Material,td.SampleNumber,td.Modulus) end |
このコードについての詳細は、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 | 関数 |
end end |
|