「クラス (コンピュータ)」の版間の差分

削除された内容 追加された内容
m編集の要約なし
オブジェクト指向とオブジェクトコード/オブジェクトファイルを混同していると思わしき記述を削除。
1行目:
{{複数の問題
[[プログラミング]]における'''クラス'''({{lang-en-short|class}})とは、既成のプログラムを再利用するボトムアップ型開発において、コンパイル済みファイル<ref>ソースコードをアセンブラあるいはコンパイラが処理して生成されるもので、単独あるいは他の"プログラム部品"と結合した上で実行可能となるデータファイルは'''オブジェクト'''(object)と呼ばれる。[[#川合(1982)|川合(1982)]] p.43</ref>の生成に相当する操作を言語内部で行うための構文を言う。操作法の統一のため抽象データ型として表現されることが多いが、概念的にクラス構文から生成される要素は並列実行も可能であり通常のデータ型とは異なる。
|独自研究=2019年1月
|正確性=2019年1月
}}
 
[[オブジェクト指向プログラミング]]における'''クラス'''({{lang-en-short|class}})<ref>英語の class は、本来「分類」「種類」といった意味を持っている。</ref>とは、[[オブジェクト (プログラミング)|オブジェクト]]を生成するための設計図あるいはひな形に相当するものである。[[抽象データ型]]の一つ。クラスから生成したオブジェクトの実体のことを[[インスタンス]]という。
 
クラスには、クラス自身またはクラスのインスタンスが保持する'''[[データ]]'''と、データに関連したオブジェクトの'''振る舞い'''を記述できる。プログラミング言語によっては、それぞれに{{仮リンク|アクセス修飾子|en|Access modifiers}}を指定できる。[[統一モデリング言語]] (UML) の[[クラス図]]では、データのことを「[[属性]]」、振る舞いのことを「操作」と呼ぶ。[[Java]]などでは、データのことを「[[フィールド (計算機科学)|フィールド]]」、振る舞いのことを「[[メソッド (計算機科学)|メソッド]]」と呼ぶ。[[C++]]などでは、データのことを「メンバー変数」、振る舞いのことを「メンバー関数」と呼ぶ。
 
クラスの概念は、クラスベースの[[オブジェクト指向プログラミング]]の基本であり、また[[カプセル化]]・[[継承 (プログラミング)|継承]]・[[ポリモーフィズム]]などの、[[オブジェクト指向プログラミング]]の実施における重要な概念を実現する基礎的な手段である。
 
プログラミング言語におけるクラスのサポートは、ダイクストラの[[構造化プログラミング]]の欠点を補う技法として[[オーレ=ヨハン・ダール]]によって[[Simula|Simula67]]において初めて導入された。クラスの構文は、[[オブジェクト指向プログラミング]]の基本である
 
ダイクストラの[[構造化プログラミング]]の欠点を補う技法として[[オーレ=ヨハン・ダール]]によって[[Simula|Simula67]]において初めて導入された。クラスの構文は、[[オブジェクト指向プログラミング]]の基本である。
== 概要 ==
{{独自研究|section=1|date=2019年1月}}
{{正確性|section=1|date=2019年1月}}
ダイクストラの[[構造化プログラミング]]は、プログラムの大規模開発への道を開いたが、あくまで単一スレッド(single thread)計算機を前提としたトップダウン型開発方法であった。すなわち、プログラムのすべての機能は単線の計算プロセス上で実行する必要があり、たとえ甲と乙という汎用的な単機能を提供する検証済みのプログラムがそれぞれ独立に存在していても、両機能を実現するプログラムを作成するためには、ソースコードから該当機能部分を抜き出し、単線上に乗るように連接(concatenation)した上で、一つのプログラムとして正しく動作するように修正し、さらに再度検証しなければならない。
 
一方で、複数スレッド(multi thread)計算機においては、主プログラムから、甲と乙のプログラムなどの従プログラムをそれぞれ並列に実行させた上で、処理内容を従プログラムに(OSの機能などを仲介して)伝言受け渡し(message passing)して代わりに処理させることで、検証済みプログラムのソースコードに手を加えることなく、低コストで開発することができる(以下、これを{{独自研究範囲|date=2019年1月|第0世代オブジェクト指向プログラミング}}と呼ぶ)<ref>ただし、随所にOSの機能を利用することになるため異なるOSへの移植性が低い上に、主プログラムと並列呼び出しする従プログラムが異なる言語で記述されている場合、複数の異なるコンパイラが必要となり、場合によっては複数の異なる言語を使用しなければならなくなってしまう。</ref>。
 
[[オーレ=ヨハン・ダール]]と[[アントニー・ホーア]]は、この第0世代オブジェクト指向プログラミングのような考え方の有効性を主張し<ref>[[#構造化プログラミング(1975)|構造化プログラミング(1975)]] pp.201-202</ref>、上記のような一連の操作を一つの言語の中で完結させるための機構を提案した。それがクラスの構文である。
13 ⟶ 25行目:
* 主プログラムと従プログラムに相当するものが異なる言語で記述されることがない。
* 複数スレッド計算機のOSに依存した以下の一連の操作を言語内部で統一的に処理できるようになる
** ソースコードのコンパイルによるオブジェクトファイル(object file)の生成、
** 主プログラムからのメモリ割り当て
** 並列呼び出し
* 抽象データ型として表現される場合、OSを仲介した伝言のやりとりのような形式ではなく、体裁上は具体的データ型のデータに対する処理への引数渡し、処理返しとして取り扱い可能になる
</ref>。
 
クラスは、[[カプセル化]]・[[継承 (プログラミング)|継承]]・[[ポリモーフィズム]]などの、[[オブジェクト指向プログラミング]]の実施を実現する基礎的な手段である。
 
== クラス設計のための基本概念 ==
=== カプセル化 ({{Lang|en|encapsulation}}) ===
{{main|カプセル化}}
一般にどんなプログラムであれ、プログラム機能を提供するためにはデータを保有するだけではなくその機能の中でその、データに対する操作ができなければならない。同様して、クラスにおいても、複数のデータだけでなくその操作も保有すをまとめ必要がある。クラス本体におい手段とし局所的に宣言される変数や操作などをクラスの'''所属物'''(attribute)<ref>[[統一モデリングC言語|UML]]では「[[属性構造体]]や[[Pascal]]のレコード型う。</ref><ref>った形で従来の[[手続き型プログラミング]]言語によっおいは、アクセス修飾子(access modifiers)が付与も提供されることもあている。</ref>一方クラスは、データだけでなくそのデータに関連する操作もひ呼ぶ<ref name=sp202 />まとめにして管理する枠組みを提供する
 
このように関連する変数や操作などをクラスの所属物として一つにまとめてしまうことを、クラスによる情報の[[カプセル化]](encapsulation)と呼ぶ。適切なカプセル化により、データ構造やアルゴリズムの変更などに伴う変更したとしても、変更箇所はカプセル化されたクラス領域内の変更箇所だけで済み、変更箇所の散逸クラス外の関連ソースコード全体に広がるまで散乱・波及してしまうことを防ぐことができる。
 
またアクセス修飾子 (access modifier) により、所属物に対して公開/非公開情報の区別をつけることで、クラス外部からクラス内に対して破壊的操作を加えることを防いだり、企業秘特定の機的情報データ保有する場合クラス外部から見ることができないようにしたりするなど、他人外部に開放する情報に制限をつけることができる。カプセル化した上に公開/非公開情報の区別を加えることを'''情報隠蔽'''(information hiding)と呼ぶ<ref>[[#落水(1993) | 落水(1993) ]] p.82</ref><ref>多くのプログラミング言語ではフィールドやメソッドの定義とアクセス権の指定は同時になされるため、カプセル化と情報隠蔽はしばしば混同される。
</ref>。
 
=== 継承 ({{Lang|en|inheritance、extension、generalization)}} ===
{{main|継承 (プログラミング)}}
複数のクラスを連接させて一つの新しいクラスを作成することを[[多重継承]]と呼ぶ<ref>[[Simula|Simula67]]においては、2つのクラスを単純に連接させることで新しいクラスを作成することはそのまま連接(concatenation)と呼ばれた。[[#構造化プログラミング(1975)|構造化プログラミング(1975)]] p.226</ref>。多重継承により、基となった全てのクラスの所属物は合わせて一つになり、全ての動作が組み合わさった新しい一つのクラスが構成される。ただし、多重継承はいくつかの問題点が指摘されており、一つのクラスに基づいてその拡張を行う単一継承、単に'''継承'''(inheritance)または拡張(extension)<ref>[[統を用いることがモデリング言語|UML]]般的は'''汎化''' ({{Lang|en|generalization}}) と呼んでい<ref>
</ref>を用いることが一般的である<ref>
多重継承は、二つのクラスの同名メソッドの[[オーバーライド]]によるコンフリクトを始めとするいくつかの問題点が指摘されており、[[Java]]、[[C Sharp|C#]]、[[D言語]]等では[[実装多重継承]]はサポートされておらず、[[インタフェース (情報技術)|インタフェース]]多重継承のみサポートされている。
</ref>。
 
継承の目的は、単純なクラスに基づいてもっと複雑なクラスを構成することである。また、複雑なクラスはそれを定義する単純なクラスに従属するという意味で、クラスに階層をつけることができるようになる<ref>[[#構造化プログラミング(1975)|構造化プログラミング(1975)]] p.226</ref><ref>これが、ダールとホーアの論文の題名である『階層的プログラム構造』である。[[#ダール(1972)|ダール(1972)]]</ref>。継承の基になったクラスを'''親クラス''''''基本クラス'''/'''基底クラス'''/'''[[スーパークラス (計算機科学)|スーパークラス]]'''などといい、継承してできたクラスを'''子クラス''''''派生クラス''''''[[サブクラス (計算機科学)|サブクラス]]'''などという。
 
UMLでは継承のことを'''汎化''' ({{Lang|en|generalization}}) と呼んでいる。汎化とはスーパークラスによる抽象化であり、対義語の特化 ({{lang|en|specialization}}) はサブクラスによる具象化を指す。
 
また、[[オブジェクト指向]]を効率よく使いこなすためには継承だけでなく[[集約]] ({{Lang|en|aggregation}})、[[委譲]] ({{Lang|en|delegation}}) を理解する必要がある。
 
継承は、単純な基本クラスからより複雑な派生クラスを構成する機構であるが、逆に複雑なクラスの所属物のいくつかを除いて単純なクラスを構成する機構は、バグが容易に入り込むことが見込まれる{{要説明|date=2019年1月}}ので、ふつう存在しない。
=== ポリモーフィズム ({{Lang|en|polymorphism}}) ===
{{main|ポリモーフィズム}}
継承は、単純な基本クラスからより複雑なクラスを構成する機構であるが、逆に複雑なクラスの所属物のいくつかを除いて単純なクラスを構成する機構は、バグが容易に入り込むことが見込まれるので、ふつう存在しない。
 
すなわち、最初から多数の所属物をカプセル化したり、基本クラスから継承するにしても多数の所属物を付け加えて極めて特化されたクラスを最初から作成してしまうと、途中でそれよりやや一般的なクラスが必要になっても代替させることができない。
 
=== ポリモーフィズム ({{Lang|en|polymorphism}}) ===
継承する際に、親クラスの関数を子クラスの関数で置き換えることを'''[[オーバーライド]]'''という。オーバーライドをうまく使うと、オブジェクトによって、実質的に実行される関数が変わるようにできる。このようにして、見かけが一緒なのに動作が違うようにできることを'''[[ポリモーフィズム]](ポリモルフィズム)'''・'''多様性'''・'''多態性'''などという。
{{main|ポリモーフィズム}}
クラスを継承する際に、スーパークラスの振る舞いをサブクラスの振る舞いで上書きする(置き換える)ことを'''[[オーバーライド]]'''という。あるサブクラスのインスタンスがオーバーライドされた振る舞いを持つ場合、インスタンスの具体的な内容(クラス)が分からなくても、インスタンスに対してその振る舞いを実行するよう指示すれば、見かけがスーパークラスと同じ(すなわちインターフェイスが同じ)でありながら、インスタンスの実際のクラスに応じて実行される振る舞い(処理内容)を変えることができる。このようにして、見かけが一緒なのに動作が変わることを'''[[ポリモーフィズム]](ポリモルフィズム)'''/'''多様性'''/'''多態性'''/'''多相性'''などという。
 
== 脚注 ==
55 ⟶ 65行目:
== 関連項目 ==
{{Wiktionary|クラス}}
* [[クラス図]] -
** [[サブクラス (計算機科学)]] -
** [[スーパークラス (計算機科学)]]
* [[メソッド (計算機科学)]]
* [[フィールド (計算機科学)]]
* [[オブジェクト指向]] - [[オブジェクト指向プログラミング]]