オブジェクト指向とは、プログラムひいてはシステムにおける構成要素を
オブジェクトとして捉える概念である。
オブジェクト指向におけるプログラミングとは特定のデータ構造と振る舞いを持つものを全て物体(オブジェクト)として捉える概念である。
オブジェクト指向では、システム上における、構成要素を分析し、その特徴をまとめてクラスとして定義する。プログラム実行時にクラスの中身としてのデータ群を具体的に決定し、メモリ上にそのデータ群をまとめて配置した塊をオブジェクトと呼ぶ。
クラスにはそのオブジェクトが、どのような内部状態を持つか、どのような操作でどのように内部状態を変化させるべきかを記述する。クラスの構造がプログラム実行前に静的に決まって変更できない言語と、実行時であってもクラスの構造の変更を行える言語が存在する。
各オブジェクトが作用しあって、その内部状態を互いに変化させながら処理が進行するようなプログラムを作ることがオブジェクト指向プログラミングである。オブジェクト指向言語と呼ばれる言語を使用したとしても、必ずしもオブジェクト指向プログラミングとなるわけではない。
オブジェクト指向プログラミングにおいて、クラスの概念を持つ言語でプログラミングする場合がほとんどである。しかしクラスというものを排除してオブジェクト指向を実現した言語(SelfやLENSなど)も存在する。
オブジェクト内のデータを隠蔽することにより「振る舞い」のみに意識させるために行う。
対象のオブジェクトの機能を引き継ぐことを指す。
オブジェクトの詳細な実装が異なっていたたとしても共通した呼び出しで利用することが出来る
オブジェクト指向はプログラマー初心者にとって、まさに最初の壁になる。しかし、それは難しく考えるからいけないのだ。もっとわかりやすく言えば、オブジェクト指向というのはクラスという一つの作業があり、それぞれにメソッドといわれる工程を伴っているものと考えればいい。
例として木版画を挙げてみよう。木版画は名の通り、まず版木に下絵を描き、それに合わせ彫刻刀で彫り、掘った版木に絵の具を付けて摺ることによって完成する作品である。そして、江戸時代には既に絵師、彫師、摺師による分業制が確立していた。これをテラオブジェクト指向wwwという呼び名で名高い(?)Rubyでオブジェクト指向で説明するとこうなる(defは関数定義。また、本来関数や変数の名称に漢字やかなは使えないのだが、あくまでわかりやすく説明するため)
class 版画
def 描く
#絵師の工程
enddef 彫る
#彫師の工程
end
def 摺る
#摺師の工程
end
end
配列が一つの単位におけるグループの集まり(配列を学校の学年、インデックスをクラス番号と思えばいいだろう)なのに対し、オブジェクトというのは一つの単位で現す作業とその作業に必要な工程の集まりのことである(ここでは版画を制作するという作業に対し、描く、彫る、摺るという工程が一つのグループになっている。
そして、絵師が描き、描いた作品を彫師が彫る、彫った作品を摺師が摺る、という工程が行われ、最後の摺る作業が終えて、初めて一つの作品が完成するわけである。
作品 = "" #ここに作品が作られていく
版画制作 = 版画.new #今から版画を作ります
作品 = 版画制作.描く
作品 = 版画制作.彫る
作品 = 版画制作.摺る
では、このオブジェクト指向、何が便利かというと、似たような作業をグループごとにまとめることができるからである。そして、それによって高い品質を保障できることが大きい。たとえば、この工房では版画以外に彫刻、油彩なども作っている作業場があるとする。ここで彫刻の作業場で何らかのミスを犯したとしても、版画や油彩の作業場には何も影響がない。これと同じ理屈で、クラス内で起きたバグは、クラス内だけを見直せば済むからである。この作業工程の隠蔽(他の作業場には版画の作業工程は見えない)のことを、カプセル化という。
また、上の版画制作にあたる変数は、インスタンスという。よく、オブジェクト指向を説明したサイトでは雛形などと説明しており、いわば作業マニュアルのようなものである。そして、このインスタンスは基本、与えられた工程以外の作業を命令することはない。つまり、版画という作業(クラス)に対し、版画制作というインスタンスが与えられることによって、その版画の題材が北斎だろうが広重だろうが、どれも同じように、描く、彫る、摺るという作業が行われるからである。このように、一度作業マニュアルを作ってしまえば、後は同じ作業を繰り返し行える特性をインヘリタンス(継承)という。
上記の例でいえば、版画における絵師の描く仕事にも構図、描画などの工程がある。また、彫師には彫るなど、摺師には絵の具の調合や摺るなどの作業工程があり、細分化されている。その場合、継承クラスを定義することによって、版画の作業を更に細分化することができる。このうち、版画における絵師の作業を継承クラス化してRubyで表すとこう表現できる。
class 絵師 < 版画
def 構図
#構図をとる工程
end
def 描画
#描く工程
end
end
これが継承クラスであり、要は作業工程が更に細かい作業工程へと細分化されているわけである。
さて、オブジェクト指向において、少し解釈が面倒なのが変数の扱いであり、一般的な変数は、その関数内でしか使えなかったり、そのページ内でしか使えなかったりする。だが、オブジェクト指向の場合は、大元のクラスにおいて、クラスのグループ内ならばどこでも使える変数、そのクラスだけで使える変数、そして、どこでも使える変数などを定義することができる。この変数が及ぶ範囲をスコープという。
例でいえば、この版画の作業で、全部の工程にかかわっているものは版木、つまりは作業工程の中で絵師に鉛筆で描かれたり、彫刻刀で掘られたり、絵の具を塗られたり、紙に摺られたりしているわけである。この版木をわざわざ、描く、彫る、塗る工程ごとに版木ですと定義するのはナンセンスだろう。一方、彫刻刀、バレンという変数があったとしても、それを使用するのはそれぞれ彫師と摺師だけであるので、これを作業工程全部で使えるグローバル変数にするのも効率が悪い。つまり、作業において発生する物や出来事に対して、関係あるものとないものを振り分けることができるのが、変数のスコープの役割である。
さて、カプセル化とインヘリタンスはそこまで難しくない。だが、このポリモーフィズムを説明するには、ちょっと木版画だけでは足りないので、この版画作業場では木版画だけでなく、石版画、銅版画も作るとする。そして、石版画も同様に描く、摺る、彫るという工程があり、担当の絵師は石版画、銅版画も担当しているとしよう。すると、上述した継承クラスにいる絵師は石版画、銅版画とも継承クラスの関係にある。このように、同じ名前のメソッドを複数のクラスで使い回せるような状態のことをポリモーフィズムという。
class 木版画
def 描く
end
end
class 石版画
def 描く
end
end
class 銅版画
def 描く
end
endclass 絵師
def 描く
end
end
こういうことである。だが、ここでの説明はこれで終わりじゃないよ。
さて、オブジェクト指向の大まかな概念がわかってきたところで、頻出する抽象クラス、インターフェースの説明をしたいと思う。抽象クラスとは名の通り「具体的なことが記されていない工程」にあたり、上の例だと、絵師クラスの描く仕事がそれに当たる。なぜなら、絵師は責任者から「描いて」と言われても、木版画の下絵なのか石版画の下絵なのか、銅版画の下絵なのか、それとも別の業務なのかわからない(つまり、抽象的にしか工程が命令されていない)からである。
だが、同時に版木が渡されたら「ああ、木版画ですね」とわかるし、石板、銅板ならそれぞれ石版画、銅版画とわかるだろう。このように、抽象クラスの場合は、必ず、それの抽象的な「描いて」という作業に対し、何を「描く」のか判別する材料は準備されており、その作業工程が上位クラスに必ず用意されている。また、インスタンスも直接継承クラスに対して指示しないとエラーとなる。なぜなら、木版画という上位クラスに「描いて」という命令を出しても、そこにあるのは作業マニュアルだけで、絵師は継承クラスにしか存在しないからである。
対してインターフェースというのは逆の視点となる。それこそ版画の作業場では木版画にしても、石版画にしても銅版画にしても、絵師に作業を頼むことになるからであり、言い換えれば絵師は木版画や石版画、銅版画…の継承クラスに位置するわけである。
では、クラスという概念との違いについてであるが、クラスは、作業は複雑な工程があるけど、それによって作られるものは同一種である。それに対しインターフェースは、作業は同じなんだけど、それによって作られるものはいっぱいあるということである。つまり、上記の例では木版画、石版画、銅版画などをひっくるめても、結局は描く、彫る、摺るという同じ作業が行われているからである。
なお、継承クラスは複数の親クラスを指定できないが、インターフェースの場合は複数の親を持つことができる大きな違いがある。
さて、今までは同じ作業の中で工程をグループ化するものと定義してきたが、実際はそうでないケースもある。それが静的メンバであり、ここではクラスに値するものはただの枠組みでしかなく、クラス名によってカテゴライズしているだけである。たとえば、アメリカ合衆国はカジノが合法化されている州とそうでない州があるが、それでも同じアメリカにある州に越したことはない。だが、実際その州のカジノが合法であるかは、実際そこに行かないとわからない。だが、逆にそれさえわかってしまえば、別に作業を工程化しているわけでもないので、そのメンバは他のメンバとは直接に関係を持っていないことがわかる(仮に50州のカジノ情報があったとしても、利用者は全部覗かなくても、必要な州の情報さえわかればいいので)。つまり、今まではダイナミックな作業という動きがあったのに対し、このメンバはお互いに他のメンバに全く干渉していないので、静的な働きしかしないため、静的メンバと呼ばれているのである(なお、メンバはメソッドともいうが、メソッドが働きをするニュアンスに対し、メンバとはただカテゴリーに属する存在《メンバー》に過ぎない)
もっとわかりやすくいえば、予めアメリカ合衆国とクラスを定義しようとしてインスタンスを作らなくても、いきなりアメリカ合衆国にあるネバダ州、アメリカにあるテネシー州という風に直接メンバを参照すれば、そこでカジノができるかどうか分かるわけであり、むしろ静的メンバにおいてはインスタンスの生成はできない(する必要がないから)。また、仮に別の国に同じ名前があったとしても、最初からアメリカのネバダ州、とカテゴリーを宣言しているわけだから、多様性も保障されることになる。
急上昇ワード改
最終更新:2025/12/12(金) 21:00
最終更新:2025/12/12(金) 21:00
ウォッチリストに追加しました!
すでにウォッチリストに
入っています。
追加に失敗しました。
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。