クラス(コンピュータプログラミング)

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

オブジェクト指向プログラミングでは、クラスオブジェクトを作成するための拡張可能なプログラムコードテンプレートであり、状態(メンバー変数)と動作の実装(メンバー関数またはメソッド)の初期値を提供します[1] [2]多くの言語では、クラス名はクラスの名前(テンプレート自体)、クラスのデフォルトコンストラクターの名前(オブジェクトを作成するサブルーチン)、およびオブジェクトのタイプとして使用されます。クラスをインスタンス化することによって生成されます。これらの明確な概念は簡単に混同されます。[2] しかし、混乱の点で、それはその多形性のために言語に固有の機能であり、なぜこれらの言語は多形性が存在しない言語と比較して非常に強力で動的で使用に適応できるのかを主張することができます。したがって、動的システム(つまり、実世界、機械学習、AI)をより簡単にモデル化できます。

クラスのコンストラクターによってオブジェクトが作成される場合クラス全体で共有されるクラス変数とは対照的に、結果のオブジェクトはクラスのインスタンスと呼ばれ、オブジェクトに固有のメンバー変数はインスタンス変数と呼ばれます

一部の言語では、クラスはコンパイル時の機能にすぎません(新しいクラスは実行時に宣言できません)が、他の言語では、クラスは第一級市民であり、通常はそれ自体がオブジェクトです(通常はClass型など)。これらの言語では、クラスを作成するクラスはメタクラスと呼ばれます。

クラスとタイプ

カジュアルな使用では、オブジェクトの「クラス」を参照することがよくありますが、狭義には、オブジェクトにはタイプがあります。つまり、インターフェイス、つまりメンバー変数のタイプ、メンバー関数(メソッド)のシグネチャ、およびこれらが満たすプロパティです。同時に、クラスには実装(具体的にはメソッドの実装)があり、特定の実装で特定のタイプのオブジェクトを作成できます。[3]型理論の観点から、クラスは実装であり、「具体的な データ構造とサブルーチンのコレクション」であり、型はインターフェースです。異なる(具体的な)クラスは、同じ(抽象)型のオブジェクトを生成できます(型システムによって異なります)。たとえば、タイプStackSmallStack(小さなスタックでは高速ですが拡張性は低い)とScalableStack(小さなスタックでは拡張性は高いがオーバーヘッドが高い)の2つのクラスで実装される可能性があります 。同様に、特定のクラスにはいくつかの異なるコンストラクターが含まれる場合があります。

クラスタイプは通常、人、場所、物、または名詞化されたものなどの名詞を表し、クラスはこれらの実装を表します。たとえば、バナナタイプは一般的なバナナのプロパティと機能を表し、 ABCBananaクラスとXYZBananaクラスはバナナの製造方法を表します(たとえば、バナナサプライヤ、またはビデオゲームでバナナを表現および描画するためのデータ構造と関数)。ABCBananaクラスは、特定のバナナを生成できます。ABCBananaクラスのインスタンスは、バナナタイプオブジェクトになります。多くの場合、型の単一の実装のみが指定されます。その場合、クラス名は多くの場合、型名と同じです。

設計と実装

クラスは、構造的および行動的構成要素から構成されます。[4] プログラミング構造としてクラスを含むプログラミング言語は、さまざまなクラス関連機能のサポートを提供し、これらの機能を使用するために必要な構文は、プログラミング言語ごとに大きく異なります。

構造

クラスのUML表記

クラスには、データ フィールドの説明(またはプロパティフィールドデータメンバー、または属性)が含まれます。これらは通常、プログラムの実行時に状態変数に関連付けられるフィールドタイプと名前です。これらの状態変数は、クラスまたはクラスの特定のインスタンスに属します。ほとんどの言語では、クラスによって定義された構造によって、そのインスタンスが使用するメモリのレイアウトが決まります。他の実装も可能です。たとえば、Pythonのオブジェクトは連想キー値コンテナーを使用します。[5]

Eiffelなどの一部のプログラミング言語は、クラスの定義の一部として不変条件の指定をサポートし、型システムを介してそれらを強制します。クラスの不変条件を強制できるようにするには、状態の カプセル化が必要です。

行動

クラスまたはそのインスタンスの動作は、メソッドを使用して定義されます。メソッドは、オブジェクトまたはクラスを操作する機能を備えたサブルーチンです。これらの操作は、オブジェクトの状態を変更したり、単にオブジェクトにアクセスする方法を提供したりする場合があります。[6] さまざまな種類のメソッドが存在しますが、それらのサポートは言語によって異なります。一部のタイプのメソッドはプログラマーコードによって作成および呼び出されますが、コンストラクター、デストラクタ、変換演算子などの他の特別なメソッドは、コンパイラーによって生成されたコードによって作成および呼び出されます。言語によって、プログラマーはこれらの特別なメソッドを定義して呼び出すこともできます。[7] [8]

クラスインターフェースの概念

すべてのクラスは、構造と動作を提供することによってインターフェースを実装(または実現)します。構造はデータと状態で構成され、動作はメソッドの実装方法を指定するコードで構成されます。[9]インターフェースの定義とそのインターフェースの実装には違いがあります。ただし、クラス宣言はインターフェイスを定義および実装するため、この線は多くのプログラミング言語ではあいまいです。ただし、一部の言語は、インターフェースと実装を分離する機能を提供します。たとえば、抽象クラスは、実装を提供せずにインターフェイスを定義できます。

クラス継承をサポートする言語では、クラスが派生元のクラスからインターフェイスを継承することもできます。

たとえば、「クラスA」が「クラスB」を継承し、「クラスB」がインターフェイス「インターフェイスB」を実装する場合、「クラスA」は「インターフェイスB」によって提供される機能(定数およびメソッド宣言)も継承します。

アクセス指定子をサポートする言語では、クラスのインターフェースは、メソッドと属性の両方を含む、クラスのパブリックメンバーのセットと見なされます(暗黙のgetterメソッドとsetterメソッドを介して)。プライベートメンバーまたは内部データ構造は、外部コードに依存することを意図していないため、インターフェイスの一部ではありません。

オブジェクト指向プログラミングの方法論では、クラスのインターフェイスの操作は互いに独立している必要があります。その結果、インターフェイスのクライアントがインターフェイスで宣言されたメソッドを使用する階層化された設計になります。インターフェイスでは、クライアントが特定の順序で1つのインターフェイスの操作を呼び出す必要はありません。このアプローチには、クライアントがオブジェクトにアクセスできるときはいつでも、インターフェイスの操作が使用可能であるとクライアントコードが想定できるという利点があります。[10] [要出典]

テレビの前面にあるボタンは、テレビとプラスチックケースの反対側にある電気配線との間のインターフェイスです。 「電源」ボタンを押して、テレビのオンとオフを切り替えます。この例では、特定のテレビがインスタンスであり、各メソッドはボタンで表され、すべてのボタンが一緒にインターフェイスを構成します(同じモデルの他のテレビセットも同じインターフェイスを持ちます)。最も一般的な形式では、インターフェースは、メソッドの関連する実装を伴わない、関連するメソッドのグループの仕様です。

テレビには、サイズや色をサポートするかどうかなど、無数の属性があり、これらが一緒になって構造を構成します。クラスは、属性(構造)とボタン(インターフェイス)を含む、テレビの完全な説明を表します。

製造されたテレビの総数を取得することは、テレビクラスの静的な方法である可能性があります。このメソッドは明らかにクラスに関連付けられていますが、クラスの個々のインスタンスのドメイン外にあります。すべてのテレビオブジェクトのセットから特定のインスタンスを見つける静的メソッドは、別の例です。

メンバーのアクセシビリティ

以下は、アクセス指定子の一般的なセットです:[11]

  • Private(またはclass-private)は、クラス自体へのアクセスを制限します。同じクラスの一部であるメソッドのみがプライベートメンバーにアクセスできます。
  • Protected(またはclass-protected)により、クラス自体とそのすべてのサブクラスがメンバーにアクセスできるようになります。
  • パブリックとは、任意のコードがその名前でメンバーにアクセスできることを意味します。

多くのオブジェクト指向言語は上記のアクセス指定子をサポートしていますが、それらのセマンティクスは異なる場合があります。

オブジェクト指向設計では、アクセス指定子をパブリックメソッド実装の注意深い設計と組み合わせて使用​​して、クラスの不変条件(オブジェクトの状態に対する制約)を適用します。アクセス指定子の一般的な使用法は、クラスの内部データをそのインターフェースから分離することです。内部構造はプライベートになり、パブリックアクセサーメソッドを使用してそのようなプライベートデータを検査または変更できます。

アクセス指定子は、プライベートメンバーでさえクライアントの外部コードから見える可能性があるため、必ずしも可視性を制御するわけではありません。一部の言語では、アクセスできないが表示されているメンバーは実行時に参照される場合がありますが(たとえば、メンバー関数から返されたポインターによって)、クライアントコードからメンバーの名前を参照して使用しようとするとタイプチェッカーによって防止されます。[12]

さまざまなオブジェクト指向プログラミング言語は、メンバーのアクセス可能性と可視​​性をさまざまな程度に適用し、言語の型システムとコンパイルポリシーに応じて、コンパイル時または実行時に適用されます。たとえば、Java言語では、クラスのプライベートデータにアクセスするクライアントコードをコンパイルできません。 [13] C ++言語で は、プライベートメソッドは表示されますが、インターフェイスではアクセスできません。ただし、クラスのインターフェースを表す完全に抽象化されたクラスを明示的に宣言することにより、それらを非表示にすることができます。[14]

一部の言語は、他のアクセシビリティスキームを備えています。

  • インスタンスとクラスのアクセシビリティRuby、class-privateとclass-protectedの代わりに、instance-privateinstance-protectedのアクセス指定子をそれぞれサポートします。これらは、インスタンスのクラスではなく、インスタンス自体に基づいてアクセスを制限するという点で異なります。[15]
  • フレンド:C ++は、クラスのフレンド関数として明示的に宣言された関数が、プライベートまたは保護として指定されたメンバーにアクセスできるメカニズムをサポートしています。[16]
  • パスベース:Javaは、ファイルの論理パスであるJavaパッケージ内のメンバーへのアクセスの制限をサポートします。ただし、保護されたメンバーにアクセスするために、フレームワーククラスと同じパッケージにクラスを実装するようにJavaフレームワークを拡張する場合は、一般的な方法です。ソースファイルは完全に異なる場所に存在する可能性があり、別の.jarファイルにデプロイされる可能性がありますが、JVMに関する限り、同じ論理パスにあります。[11]

クラス間の関係

スタンドアロンクラスの設計に加えて、プログラミング言語は、クラス間の関係に基づいたより高度なクラス設計をサポートする場合があります。一般的に提供されるクラス間関係の設計機能は、構成的で階層的です。

構成

クラスは他のクラスで構成することができ、それによって、囲んでいるクラスとその埋め込まれたクラスの間に構成上の関係を確立します。クラス間の構成関係は、一般に、 has-a関係としても知られています。[17]たとえば、クラス「Car」は、クラス「Engine」で構成され、それを含むことができます。したがって、車にはエンジンがあります。構成の1つの側面は封じ込めです。これは、コンポーネントインスタンスを持っているインスタンスによるコンポーネントインスタンスの囲い込みです。囲んでいるオブジェクトに値ごとのコンポーネントインスタンスが含まれている場合、コンポーネントとその囲んでいるオブジェクトの有効期間は同じです。コンポーネントが参照によって含まれている場合、それらは同様の寿命を持たない可能性があります。[18] たとえば、Objective-C2.0では次のようになります。

@interface  Car  :NSObject

@property NSString * name ;  
@property Engine *エンジン  
@property NSArray *タイヤ;  

@終わり

このCarクラスには、 NSString文字列オブジェクト)、Engine、およびNSArray(配列オブジェクト) のインスタンスがあります。

階層

クラスは1つ以上の既存のクラスから派生させることができ、それによって派生元クラス(基本クラス親クラス、またはスーパークラス)および派生クラス(子クラスまたはサブクラス)。派生クラスと派生クラスの関係は、一般にis-a関係として知られています。 [19]たとえば、クラス「ボタン」はクラス「コントロール」から派生させることができます。したがって、ボタンコントロールです。親クラスの構造的および動作的メンバーは、子クラス継承継承するものに加えて、追加の構造メンバー(データフィールド)と動作メンバー(メソッド)を定義できるため特殊化です。また、派生クラスはオーバーライド 言語が許せば継承されたメソッド。

すべての言語が多重継承をサポートしているわけではありません。たとえば、Javaでは、クラスが複数のインターフェースを実装できますが、1つのクラスからのみ継承します。[20]多重継承が許可されている場合、階層は有向非巡回グラフ(または略してDAG)であり、それ以外の場合はツリーです。階層には、ノードとしてのクラスとリンクとしての継承関係があります。同じレベルのクラスは、異なるレベルのクラスよりも関連付けられる可能性が高くなります。この階層のレベルは、レイヤーまたは抽象化レベルと呼ばれます。

例(iPhoneSDKの簡略化されたObjective-C2.0コード):

@interface  UIResponder  :NSObject // ... @interface UIView  :UIResponder // ... @interface UIScrollView  :UIView // ... @interface UITableView  :UIScrollView // .. .. 
  
  
  

この例では、UITableViewUIScrollViewであり、 UIViewUIResponderであり、 NSObjectです。

サブクラスの定義

概念的には、スーパークラスはそのサブクラスのスーパーセットです。たとえば、一般的なクラス階層には、 RectangleEllipseのスーパークラスとしてGraphicObjectが含まれ、SquareはRectangleのサブクラスになります。これらはすべて集合論のサブセット関係です。つまり、すべての正方形は長方形ですが、すべての長方形が正方形であるとは限りません。

一般的な概念上のエラーは、サブクラスとの関係の一部を間違えることです。たとえば、車とトラックはどちらも車両の種類であり、車両クラスのサブクラスとしてモデル化するのが適切です。ただし、自動車の構成部品をサブクラスの関係としてモデル化するのはエラーになります。たとえば、車はエンジンとボディで構成されていますが、エンジンやボディを車のサブクラスとしてモデル化することは適切ではありません。

では、オブジェクト指向モデリングの関係のこれらの種類は、一般的に、オブジェクトのプロパティとしてモデル化されています。この例では、Carクラスにはpartsというプロパティがあります部品は、このようなのインスタンスとしてオブジェクトのコレクションを保持するために入力されたことになるボディエンジンタイヤなどを、のようなオブジェクトモデリング言語UMLオブジェクトのカーディナリティ、入力値と出力値の制約などのデータなど、「の一部」やその他の種類の関係のさまざまな側面をモデル化する機能が含まれます。この情報は、開発者ツールが基本以外の追加コードを生成するために利用できます。getメソッドとsetメソッドのエラーチェックなど、オブジェクトのデータ定義[21]

オブジェクトクラスのシステムをモデル化および実装する際の重要な質問の1つは、クラスが1つ以上のスーパークラスを持つことができるかどうかです。実際のセットがある現実の世界では、他の複数のセットと交差していないセットを見つけることはめったにありません。ただし、FlavoursやCLOSなどの一部のシステムは、実行時に複数の親がそうする機能を提供しますが、オブジェクト指向コミュニティの多くは、そもそもオブジェクトクラスを使用するという目標とは正反対であると考える複雑さをもたらします。複数のスーパークラスを処理する場合、メッセージの処理を担当するクラスを理解することは複雑になる可能性があります。この機能を不注意に使用すると、同じシステムの複雑さの一部が発生する可能性があり、あいまいさのクラスは回避するように設計されています。[22]

SmalltalkやJavaなどの最新のオブジェクト指向言語では、実行時に単一の継承が必要です。これらの言語の場合、多重継承はモデリングには役立ちますが、実装には役立ちません。

ただし、セマンティックWebアプリケーションオブジェクトには複数のスーパークラスがあります。インターネットの変動性にはこのレベルの柔軟性が必要であり、Webオントロジー言語(OWL)などの技術標準はそれをサポートするように設計されています。

同様の問題は、実行時にクラス階層を変更できるかどうかです。 Flavours、CLOS、Smalltalkなどの言語はすべて、メタオブジェクトプロトコルの一部としてこの機能をサポートしています。クラス自体はファーストクラスのオブジェクトであるため、適切なメッセージを送信することで、クラスの構造を動的に変更することができます。 JavaやC ++など、強い型付けに重点を置いている他の言語では、実行時にクラス階層を変更することはできません。セマンティックWebオブジェクトには、実行時にクラスを変更する機能があります。合理性は、複数のスーパークラスを許可する理由に似ています。インターネットは非常に動的で柔軟性があるため、この変動性を管理するには階層を動的に変更する必要があります。[23]

クラスの概念と継承の直交性

クラスベース言語は一般に継承をサポートすると想定されていますが、継承はクラスの概念の本質的な側面ではありません。「オブジェクトベース言語」と呼ばれることが多い一部の言語は、クラスをサポートしていますが、継承をサポートしていません。オブジェクトベースの言語の例には、以前のバージョンのVisualBasicが含まれます。

オブジェクト指向分析内

オブジェクト指向分析およびUMLでは、2つのクラス間の関連付けは、クラスまたはそれに対応するインスタンス間のコラボレーションを表します。協会には方向性があります。たとえば、2つのクラス間の双方向の関連付けは、両方のクラスがそれらの関係を認識していることを示します。[24]アソシエーションは、その名前または目的に応じてラベル付けされる場合があります。[25]

アソシエーションロールには、アソシエーションの終わりが与えられ、対応するクラスのロールを記述します。たとえば、「subscriber」ロールは、クラス「Person」のインスタンスがクラス「Magazine」との「subscribes-to」アソシエーションに参加する方法を記述します。また、「雑誌」は同じ協会で「購読雑誌」の役割を担っています。アソシエーションロールの多重度は、アソシエーションの他のクラスの各インスタンスに対応するインスタンスの数を表します。一般的な多重度は、「0..1」、「1..1」、「1 .. *」、「0 .. *」です。ここで、「*」は任意の数のインスタンスを指定します。[24]

クラスの分類

クラスには多くのカテゴリがあり、そのうちのいくつかは重なり合っています。

抽象的で具体的な

継承をサポートする言語では、抽象クラス、または抽象基本クラス(ABC)は、抽象としてラベル付けされているか、単に抽象メソッド(または仮想メソッド)を指定しているため、インスタンス化できないクラスです。抽象クラスは、いくつかのメソッドの実装を提供する場合があり、抽象クラスの直接または間接の子孫によって実装される署名を介して仮想メソッドを指定する場合もあります。抽象クラスから派生したクラスをインスタンス化する前に、その親クラスのすべての抽象メソッドを、派生チェーン内のあるクラスによって実装する必要があります。[26]

ほとんどのオブジェクト指向プログラミング言語では、プログラマーはどのクラスを抽象と見なすかを指定でき、これらをインスタンス化することはできません。たとえば、JavaC#、およびPHPでは、キーワードabstractが使用されます。[27] [28] C ++では、抽象クラスは、その言語の適切な構文(C ++用語では純粋仮想関数)によって与えられる少なくとも1つの抽象メソッドを持つクラスです。[26]

仮想メソッドのみで構成されるクラスは、C ++ではPureAbstract Base Class(またはPure ABC )と呼ばれ、言語のユーザーにはインターフェイスとしても知られています。[14]他の言語、特にJavaとC#は、言語のキーワードを介してインターフェースと呼ばれる抽象クラスのバリアントをサポートします。これらの言語では、多重継承は許可されていませんが、クラスは複数のインターフェースを実装できます。このようなクラスには、公的にアクセス可能な抽象メソッドのみを含めることができます。[20] [29] [30]

具象クラスは、インスタンス化できないクラスとは対照的に、インスタンス化できるクラスです

ローカルおよび内部

一部の言語では、クラスはグローバルスコープ以外のスコープで宣言できます。このようなクラスにはさまざまな種類があります。

内部クラスは、別のクラス内で定義されたクラスです。内部クラスとそれを含むクラスの間の関係は、別のタイプのクラス関連付けとして扱うこともできます。内部クラスは通常、囲んでいるクラスのインスタンスに関連付けられておらず、囲んでいるクラスとともにインスタンス化されていません。言語によっては、囲んでいるクラスの外部からクラスを参照できる場合とできない場合があります。関連する概念は内部型であり、内部データ型またはネスト型とも呼ばれ、内部クラスの概念を一般化したものです。C ++は、内部クラスと内部型の両方をサポートする言語の例です(typedef宣言を介して)。[31][32]

もう1つのタイプは、プロシージャまたは関数内で定義されたクラスであるローカルクラスです。これにより、クラス名への参照が、クラスが宣言されているスコープ内に制限されます。言語のセマンティックルールによっては、非ローカルクラスと比較してローカルクラスに追加の制限がある場合があります。一般的な制限の1つは、ローカルクラスメソッドが囲んでいる関数のローカル変数にアクセスできないようにすることです。たとえば、C ++では、ローカルクラスは、それを囲む関数内で宣言された静的変数を参照できますが、関数の自動変数にはアクセスできません。[33]

メタクラス

メタクラスは、インスタンスがクラスであるクラスです。[34]メタクラスは、クラスのコレクションの一般的な構造を記述し、デザインパターンを実装したり、特定の種類のクラスを記述したりできます。メタクラスは、フレームワークを記述するためによく使用されます。[35]

PythonRubySmalltalkなどの一部の言語では、クラスもオブジェクトです。したがって、各クラスは、言語に組み込まれている一意のメタクラスのインスタンスです。 [5] [36] [37] Common Lispのオブジェクトシステム(CLOS)を提供するメタオブジェクトプロトコルこれらのクラスとメタクラスを実装する(モップ)。 [38]

サブクラス化不可

サブクラス化できないクラスを使用すると、プログラマーは、階層のあるレベルでそれ以上の派生が禁止されているクラスとクラスの階層を設計できます(スタンドアロンクラスもサブクラス化不可として指定され、階層の形成を防ぐことができます)。これを抽象クラスと比較してください。抽象クラスは、使用するために派生を暗示し、奨励し、必要とします。サブクラス化できないクラスは暗黙的に具象です。

サブクラス化できないクラスはsealed、C#のようfinalに、またはJavaやPHPのようにクラスを宣言することによって作成されます。[39] [40] [41]たとえば、JavaのStringクラスはfinalとして指定されます。[42]

サブクラス化できないクラスにより、コンパイラー(コンパイルされた言語)は、サブクラス化可能なクラスでは使用できない最適化を実行できる場合があります。[43]

クラスを開く

オープンクラスは変更可能なクラスです。通常、実行可能プログラムは顧客が変更することはできません。開発者は多くの場合、一部のクラスを変更できますが、通常、標準または組み込みのクラスを変更することはできません。Rubyでは、すべてのクラスが開いています。Pythonではクラスは実行時に作成でき、後ですべてを変更できます。[44] Objective-Cカテゴリを使用すると、プログラマは既存のクラスを再コンパイルしたり、そのソースコードにアクセスしたりすることなく、既存のクラスにメソッドを追加できます。

Mixins

一部の言語はミックスインを特別にサポートしていますが、多重継承のある言語では、ミックスインは単にis-a-type-of関係を表さないクラスです。ミックスインは通常、同じメソッドを複数のクラスに追加するために使用されます。たとえば、クラスUnicodeConversionMixinは、共通の親を共有しない クラスFileReaderおよびWebPageScraperに含まれている場合、 unicode_to_asciiと呼ばれるメソッドを提供する場合があります。

部分的

この機能をサポートする言語では、部分クラスは、定義が単一のソースコードファイル内または複数のファイルにまたがって複数の部分に分割される可能性があるクラスです。[45]これらの部分はコンパイル時にマージされ、コンパイラの出力は非部分クラスの場合と同じになります。

部分クラスを導入する主な動機は、ビジュアルデザイナーなどのコードジェネレーターの実装を容易にすることです。[45]それ以外の場合、開発者が作成したコード内にインターリーブされたときに生成されたコードを管理できるコードジェネレーターを開発することは、課題または妥協点です。部分クラスを使用すると、コードジェネレーターは個別のファイルまたはファイル内の粗粒度の部分クラスを処理できるため、生成されたコードを大規模な解析によって複雑に挿入する必要がなくなり、コンパイラの効率が向上し、開発者コードが破損する潜在的なリスクが排除されます。部分クラスの単純な実装では、コンパイラーは事前コンパイルのフェーズを実行できますここで、部分クラスのすべての部分を「統合」します。その後、通常どおりコンパイルを続行できます。

部分クラス機能のその他の利点と効果は次のとおりです。

  • 独自の方法でクラスのインターフェースと実装コードを分離できます。
  • エディター内の大きなクラスのナビゲーションを容易にします
  • アスペクト指向プログラミングと同様の方法で関心の分離を可能にしますが、追加のツールを使用する必要はありません。
  • 後で個々のコードを1つのファイルにマージすることなく、複数の開発者が1つのクラスで同時に作業できるようにします。

部分的なクラスは、かなり長い間、ClassExtensionsという名前でSmalltalkに存在してまし.NET Framework 2の登場に伴いMicrosoftはC# 2.0とVisual Basic2005の両方でサポートされる部分クラスを導入しましたWinRTは部分クラスもサポートしています。

VB.NETの例

Visual Basic .NETで記述されたこの簡単な例は、同じクラスの一部が2つの異なるファイルでどのように定義されているかを示しています。

file1.vb
部分 クラス MyClassPrivate 
    _name As String End Class _   
 
file2.vb
部分 クラス MyClass
    パブリック 読み取り専用プロパティAs String Get Return _name End GetEnd プロパティEndClass   
         
              
          
     
 

コンパイルすると、結果は次のように2つのファイルが1つとして書き込まれた場合と同じになります。

Class  MyClass 
    Private  _name  As  String 
    Public  Readonly  Property  Name () As  String 
         Get 
             Return  _name 
         End  Get 
    End  Property 
End  Class

Objective-Cの例

Objective-Cでは、カテゴリとも呼ばれる部分クラスは、次の例のように、複数のライブラリや実行可能ファイルに分散することもあります。ただし、主な違いは、Objective-Cのカテゴリが別のインターフェイス宣言の定義を上書きする可能性があることと、カテゴリが元のクラス定義と等しくないことです(最初の定義には最後の定義が必要です)。[46]代わりに、.NET部分クラスは競合する定義を持つことができず、すべての部分定義は他の定義と同じです。[45]

Foundationでは、ヘッダーファイルNSData.h:

@interface  NSData  :NSObject

-  id initWithContentsOfURL:NSURL * URL ; 
//..。

@終わり

ユーザー提供のライブラリでは、Foundationフレームワークとは別のバイナリ、ヘッダーファイルNSData + base64.h:

#import <Foundation / Foundation.h>

@interface  NSData  (base64)

-  NSString * base64String ; 
-  id initWithBase64String:NSString * base64String ; 

@終わり

そして、アプリでは、さらに別のバイナリファイル、ソースコードファイルmain.m:

#import <Foundation / Foundation.h> 
#import "NSData + base64.h"

int main int argc char * argv [])    
{{
    if argc < 2    
        EXIT_FAILUREを返します; 
    NSString * sourceURLString = [ NSString stringWithCString argv [ 1 ]];    
    NSData * data = [[ NSData alloc ] initWithContentsOfURL :[ NSURL URLWithString sourceURLString ]];      
    NSLog @ "%@" [データベース64String ]);  
    EXIT_SUCCESSを返します; 
}

ディスパッチャは、NSDataインスタンスを介して呼び出された両方のメソッドを検出し、両方を正しく呼び出します。

インスタンス化できない

インスタンス化できないクラスを使用すると、プログラマーは、クラスのインスタンスがなくても実行時にアクセスできるクラスごとのフィールドとメソッドをグループ化できます。実際、この種のクラスではインスタンス化は禁止されています。

たとえば、C#では、「static」とマークされたクラスはインスタンス化できず、静的メンバー(フィールド、メソッド、その他)のみを持つことができ、インスタンスコンストラクターを持つことはできず、封印されます。 [47]

名前なし

名前のないクラスまたは匿名クラスは、定義時に名前または識別子にバインドされていないクラスです。[48] [49]これは、名前付き関数と名前なし関数に類似しています

メリット

ソフトウェアをオブジェクトクラスに編成することの利点は、次の3つのカテゴリに分類されます。[50]

  • 急速な発展
  • メンテナンスのしやすさ
  • コードとデザインの再利用

オブジェクトクラスは、コードとユーザーの間のセマンティックギャップを減らすため、迅速な開発を容易にします。システムアナリストは、基本的に同じ語彙を使用して開発者とユーザーの両方と話し、アカウント、顧客、請求書などについて話すことができます。ほとんどのオブジェクト指向環境には強力なデバッグおよびテストツールが付属しているため、オブジェクトクラスは多くの場合迅速な開発を促進します。クラスのインスタンスを実行時に検査して、システムが期待どおりに実行されていることを確認できます。また、ほとんどのオブジェクト指向環境では、コアメモリのダンプを取得するのではなく、デバッグ機能を解釈して、開発者がプロ​​グラムのどこでエラーが発生したかを正確に分析し、どのメソッドがどの引数に対してどの引数で呼び出されたかを確認できるようにしています。[51]

オブジェクトクラスは、カプセル化によってメンテナンスを容易にします。開発者がオブジェクトの動作を変更する必要がある場合、変更をそのオブジェクトとそのコンポーネント部分だけにローカライズできます。これにより、メンテナンスの強化による望ましくない副作用の可能性が減少します。

ソフトウェアの再利用も、オブジェクトクラスを使用する主な利点です。クラスは、継承とインターフェースを介して再利用を容易にします。新しい動作が必要な場合は、多くの場合、新しいクラスを作成し、そのクラスにそのスーパークラスのデフォルトの動作とデータを継承させ、それに応じて動作またはデータの一部の側面を調整することで実現できます。インターフェイス(メソッドとも呼ばれます)を介した再利用は、別のオブジェクトが(新しい種類のオブジェクトを作成するのではなく)何らかのオブジェクトクラスを呼び出したい場合に発生します。この再利用方法は、あるプログラムが別のプログラムのコードを再利用するときにソフトウェアに侵入する可能性のある一般的なエラーの多くを取り除きます。[52]

実行時の表現

データ型として、クラスは通常、コンパイル時の構成と見なされます。[53]言語またはライブラリは、クラスに関する実行時情報を表す、またはリフレクション機能へのアクセスと実行時にデータ構造フォーマットを操作する機能を提供するメタデータを表す、プロトタイプまたはファクトリ メタオブジェクトもサポートする場合があります。多くの言語は、実行時に情報が必要ないという理由で、クラスに関するこの種の実行時型情報をクラスと区別します。一部の動的言語は、実行時とコンパイル時の構造を厳密に区別しないため、メタオブジェクトとクラスを区別できない場合があります。

たとえば、HumanがPersonクラスを表すメタオブジェクトである場合、Personクラスのインスタンスは、Humanメタオブジェクトの機能を使用して作成できます。

も参照してください

メモ

  1. ^ ガンマ等。1995年、p。14。
  2. ^ a b Bruce 2002、2.1オブジェクト、クラス、およびオブジェクトタイプ、https://books.google.com/books?id = 9NGWq3K1RwUC&pg = PA18
  3. ^ ガンマ等。1995年、p。17.17。
  4. ^ ガンマ等。1995年、p。14。
  5. ^ a b "3。データモデル"Python言語リファレンスPython SoftwareFoundation 2012年4月26日取得
  6. ^ Booch 1994、p。86-88。
  7. ^ 「クラス(I)」C ++言語チュートリアルcplusplus.com 2012年4月29日取得
  8. ^ 「クラス(II)」C ++言語チュートリアルcplusplus.com 2012年4月29日取得
  9. ^ Booch 1994、p。105。
  10. ^ Jamrich、パーソンズ、6月(2015-06-22)。新しい視点のコンピューターの概念、2016年。包括的マサチューセッツ州ボストン。ISBN 9781305271616OCLC917155105 _
  11. ^ a b "クラスのメンバーへのアクセスの制御"JavaチュートリアルOracle 2012年4月19日取得
  12. ^ 「OOP08-CPP。プライベートデータへの参照を返さないでください」CERT C ++セキュアコーディング標準カーネギーメロン大学。2010-05-10。2015-10-03にオリジナルからアーカイブされました2012年5月7日取得
  13. ^ ベンアリ、モルデハイ(2007-01-24)。「2.2識別子」(PDF)Javaでのコンパイルおよびランタイムエラー2012年5月7日取得
  14. ^ a b ワイルド、フレッド。「C ++インターフェース」ドブ博士のUBMTechweb 2012年5月2日取得
  15. ^ トーマス; ハント。「クラス、オブジェクト、および変数」Rubyのプログラミング:実用的なプログラマーズガイドRuby-Doc.org 2012年4月26日取得
  16. ^ 「友情と相続」C ++言語チュートリアルcplusplus.com 2012年4月26日取得
  17. ^ Booch 1994、p。180。
  18. ^ Booch 1994、p。128-129。
  19. ^ Booch 1994、p。112。
  20. ^ a b "インターフェイス"JavaチュートリアルOracle 2012年5月1日取得
  21. ^ Berfeld、Marya(2008年12月2日)。「IBMRationalSoftwareArchitectエディションおよび関連ソフトウェアでのUMLからJavaへの変換」IBM 2013年12月20日取得
  22. ^ Jacobsen、Ivar; マグナス・クリスターソン; パトリック・ジョンソン; ガンナーオーバーガード(1992)。オブジェクト指向ソフトウェア工学アディソン-ウェズリーACMプレス。pp。43–69。  _ ISBN 0-201-54435-0
  23. ^ Knublauch、Holger; Oberle、Daniel; テトロー、フィル; ウォレス、エヴァン(2006-03-09)。「オブジェクト指向ソフトウェア開発者のためのセマンティックWeb入門書」W3C 2008年7月30日取得
  24. ^ a b ベル、ドナルド。「UMLの基本:クラス図」開発者ワークスIBM 2012年5月2日取得
  25. ^ Booch 1994、p。179。
  26. ^ ab ポリモーフィズム」C ++言語チュートリアルcplusplus.com 2012年5月2日取得
  27. ^ 「抽象メソッドとクラス」JavaチュートリアルOracle 2012年5月2日取得
  28. ^ 「クラスの抽象化」PHPマニュアルPHPグループ2012年5月2日取得
  29. ^ 「インターフェイス(C#プログラミングガイド)」C#プログラミングガイドMicrosoft 2013年8月15日取得
  30. ^ 「継承(C#プログラミングガイド)」C#プログラミングガイドMicrosoft 2012年5月2日取得
  31. ^ 「ネストされたクラス(C ++のみ)」XL C / C ++ V8.0 forAIXIBM 2012年5月7日取得
  32. ^ 「ローカルタイプ名(C ++のみ)」XL C / C ++ V8.0 forAIXIBM 2012年5月7日取得
  33. ^ 「ローカルクラス(C ++のみ)」XL C / C ++ V8.0 forAIXIBM 2012年5月7日取得
  34. ^ Booch 1994、p。133-134。
  35. ^ 「13のクラスとメタクラス」pharo.gforge.inria.fr 2016年10月31日取得
  36. ^ トーマス; ハント。「クラスとオブジェクト」Rubyのプログラミング:実用的なプログラマーズガイドRuby-Doc.org 2012年5月8日取得
  37. ^ Booch 1994、p。134。
  38. ^ 「MOP:概念」CommonLispオブジェクトシステムのメタオブジェクトプロトコルLispユーザーの協会。2010年11月15日にオリジナルからアーカイブされました2012年5月8日取得
  39. ^ 「封印された(C#リファレンス)」C#リファレンスMicrosoft 2012年5月8日取得
  40. ^ 「最終的なクラスとメソッドの記述」JavaチュートリアルOracle 2012年5月8日取得
  41. ^ 「PHP:最終キーワード」PHPマニュアルPHPグループ2014年8月21日取得
  42. ^ "文字列(Java Platform SE 7)"Java Platform、Standard Edition 7:API仕様Oracle 2012年5月8日取得
  43. ^ ブランド、Sy。「ファイナルクラスのパフォーマンス上の利点」Microsoft C ++チームのブログMicrosoft 2020年4月4日取得
  44. ^ 「9。クラス」PythonチュートリアルPython.org 2018年3月3日取得モジュールの場合と同様に、クラスはPythonの動的な性質を利用します。クラスは実行時に作成され、作成後にさらに変更できます。
  45. ^ a b c mairaw; BillWagner; tompratt-AQ(2015-09-19)、「Partial Classes and Methods」C#プログラミングガイド、Microsoft 、 2018年8月8日取得
  46. ^ Apple(2014-09-17)、「既存のクラスのカスタマイズ」Objective-Cを使用したプログラミング、Apple 、 2018年8月8日取得
  47. ^ 「静的クラスと静的クラスメンバー(C#プログラミングガイド)」C#プログラミングガイドMicrosoft 2012年5月8日取得
  48. ^ 「匿名クラス(Java™チュートリアル> Java言語の学習>クラスとオブジェクト)」docs.oracle.com 2021-05-13を取得
  49. ^ 「PHP:匿名クラス-手動」www.php.net 2021年8月11日取得
  50. ^ 「オブジェクトとは何ですか?」oracle.comOracleCorporation 2013年12月13日取得
  51. ^ ブーチ、グレイディ; ロバートA.マクシムチュク; Michael W. Engle; ボビー・J・ヤング博士; ジム・コナレン; ケリーA.ヒューストン(2007年4月30日)。アプリケーションを使用したオブジェクト指向の分析と設計アディソン-ウェスリープロフェッショナル。pp。1–28。ISBN 978-0-201-89551-32013年12月20日取得人間の認知には根本的な制限要因があります。分解、抽象化、および階層を使用することで、これらの制約に対処できます。
  52. ^ Jacobsen、Ivar; マグナス・クリスターソン; パトリック・ジョンソン; ガンナーオーバーガード(1992)。オブジェクト指向ソフトウェア工学アディソン-ウェズリーACMプレス。ISBN 0-201-54435-0
  53. ^ 「C ++国際規格」(PDF)ワーキングドラフト、プログラミング言語C ++の標準ISO / IEC JTC1 / SC22WG21 2020年1月5日取得

参考文献

さらに読む