オブジェクト指向 単語


ニコニコ動画でオブジェクト指向の動画を見に行く

オブジェクトシコウ

7.2千文字の記事
これはリビジョン 2908685 の記事です。
内容が古い・もしくは誤っている可能性があります。
最新版をみる
長時間編集 ゆっくり編集していってね!!!
編集者の方へ:2021/4/30 23:59頃の終了を目指し作業しております。
ゆっくり編集していった結果が編集競合にならない様にご協力お願いします。

オブジェクト指向(object oriented)とは、1980年代以降ずっと主流を占めているプログラミングパラダイムである。

概要

オブジェクト指向とは、手続きをオブジェクト(対象)を単位として考えることによって、「対象を(が)〜する」という人間の思考に近い形でプログラミングしようとするプログラミングパラダイムである。カプセル化・継承・多態性が三大要素であるとされる。

C言語を代表格とする手続き型言語の欠点を修正するような形で1980年代に普及した。C言語との互換性を保ちつつオブジェクト指向を採り入れたC++はその先鋒にあたるが、元祖ではない。普及以降、関数型プログラミング派からは異論があるかもしれないが、2021年現在においても主流のプログラミングパラダイムである。

明確な定義はない?

主流かつ人気のプログラミングパラダイムであり、大抵の実用的プログラミング言語で採用されているが、各言語で実装される時に言語毎にアレンジを受けており、アレンジされたそれぞれがオブジェクト指向を名乗っている。

プログラミング解説書も売り込みのために「オブジェクト指向で〜」とキャッチコピーやタイトルに入れることが多々あり、各言語のオブジェクト指向はさらに各解説書著者による解釈を受けている。つまり、オブジェクト指向に決定的な定義はなく、著者の数だけ「オブジェクト指向」の定義があると言えるかもしれない。

だがちょっと待って欲しい。あらゆる書籍や言語がオブジェクト指向にこだわる姿を目にしすぎて、「オブジェクト指向にすれば何でも解決する」と、銀の弾丸のように思い込んではいないだろうか。存在しない「何でも解決できるオブジェクト指向の定義」を探す旅に出ているうちに、気づかないうちに「オブジェクト指向が優れているのではない。優れているものがオブジェクト指向なのだ」のような後出し逆転的論理に陥ってはいないだろうか。

以下では最大公約数的なものを目指して記述するつもりだが、読んで俺の知ってるオブジェクト指向と違うと思ったのならお互いにそういうことなのだろう。異論は認める。

クラスベース/プロトタイプベース

クラスにはそのオブジェクトが、どのような内部状態を持つか、どのような操作でどのように内部状態を変化させるべきかを記述する。クラスの構造がプログラム実行前に静的に決まって変更できない言語(クラスベース)と、実行時であってもクラスの構造の変更を行える言語(プロトタイプベース)が存在する。

オブジェクト指向プログラミングにおいて、クラスの概念を持つ言語でプログラミングする場合がほとんどである。しかしクラスというものを排除してオブジェクト指向を実現した言語(SelfやLENSなど)も存在する。

例示による詳細

以下ではプログラミング未経験者でも読めるように、出来るだけ特定のプログラミング言語に依存しない記述を試みるが、プログラミングでは実際にやってみないと実感がわかない話はたくさんある。読んでわからないのであれば、一度Javaあたりでオブジェクトやクラスを定義したプログラミングを書いてみるしかないかもしれない。なお、不備に見えるものでも説明を簡略化するためあえてそうしてあるところもある。


例示のために特殊な状況を設定する。

あなた(プログラマー)が動物園の飼育員(コンピューター)の監督に就任したとしよう。あなたは飼育員に対して飼育マニュアル(プログラム)を通じて指示することしか出来ず、自ら動物と触れ合うことは出来ない。

説明のための例示であり、実在の動物園・飼育員・監督・動物等及びその動作とは一切関係ない。異論は認めない。

Before

この動物園にはA, B, Cという名前の3頭の虎がいる。

あなたは思考を放棄してすべての手順(手続き)を逐一書き出すことにした。

飼育員の業務

虎Aに対し肉10kgを用意する。
虎A用の肉10kgを1kgごとに切り分ける。
虎Aの檻に切り分けた肉を置いてくる。
虎Aは満腹になる。
虎Bに対し肉10kgを用意する。
虎B用の肉10kgを1kgごとに切り分ける。
虎Bの檻に切り分けた肉を置いてくる。
虎Bは満腹になる。
虎Cに対し肉10kgを用意する。
虎用の肉10kgを1kgごとに切り分ける。
虎Cの檻に切り分けた肉を置いてくる。
虎Cは満腹になる。

上記でもゲシュタルト崩壊して十分読みづらいが、さらに虎の数が増えた時に収拾がつかなくなるのは、想像に難くない。間違いにも気づきにくくなる。「虎C」と書くところを「虎」としてしまっていることに初見で気づいた人はどれくらいいただろうか。

After

オブジェクト指向を導入すると、上記のマニュアルは以下のようになる。

虎は空腹になったり満腹になったりする。

餌のやり方

虎に対し肉10kgを用意する。
虎用の肉10kgを1kgごとに切り分ける。
虎の檻に切り分けた肉を置いてくる。
虎は満腹になる。

飼育員の業務

虎A, B, Cに餌をやる。

なんということでしょう

業務内容をA, B, Cという対象(object)を単位として整理するという方針に従えば(oriented)、A, B, Cは「虎」に分類(classification)されてひと括りに扱うことができるようになり、 飼育員のすることは変わっていないのにマニュアルの見通しが良くなったのである。

これなら虎の数が少々増えても読みづらくはならない。また、現実の監督が飼育員に指示する時もBeforeよりAfterのやり方になるであろうことから、より人間の考え方に近づいているということもおわかりいただけただろうか。

用語解説

  • オブジェクト(object): 操作対象のこと。上記の例では虎A, B, Cが該当する。
  • クラス(class): 上記でいう「虎」が該当する。分類という意味で学校とは関係ない
  • インスタンス(instance): 虎A, B, Cそれぞれはオブジェクト(対象)なのだが、「虎」という分類の具体例ということで「虎」クラスのインスタンス(事例)という呼び方もする。
  • メソッド(method: 方法): 上記の例では「餌のやり方」の部分が「虎」クラスのメソッドである。虎に分類される対象に対して可能な操作を記している。
  • プロパティ(property): クラスに分類される対象の状態を記録する。上記の例では「空腹・満腹」という部分が「虎」のプロパティに該当する。プログラミング言語によってメンバ(member)、フィールド(field)、アトリビュート(attribute)呼び方が異なる場合もあるが、基本理念は共通である。

オブジェクトについて

スレッドやHTTP接続、果ては関数など形のないものまでオブジェクト(対象)化できるので、オブジェクト = 物体 という考え方に囚われるとよろしくない。

厳密に言うと、対象の状態を記録したプロパティを束ねたデータの集合体であり対象そのものではない。冷静に考えれば虎「A, B, C」は、それぞれにつけられた名前であって虎そのものではないのだから当然なのであるが、これを忘れると後で虎が異次元空間に消えたり、何もないところから突然現れたりすることになる。

利点

柔軟性

後から虎の餌用の肉を1kgではなく0.5kgごとに切り分けなければならないことが判明したとしよう。オブジェクト指向導入前であれば虎A, B, Cのそれぞれについて全3ヶ所の変更が必要であったが、オブジェクト指向導入後であれば「餌のやり方」の項を1ヶ所変更するだけで済む。

虎Dが増えたとしても、オブジェクト指向なら「虎A, B, C」を「虎A, B, C, D」とするだけである。

このようにオブジェクト指向が導入されれば状況の変更にも柔軟に対応できるようになるのである。

部品化

例えば上記の「虎」の章の部分の執筆を部下に任せることができる(部下がいるほど偉ければだが)

一旦任せてしまえば、たとえば先述の肉の切り分け単位が変わったりしてもあなた自身が対応をする必要はない。

また、任された部下が、空腹か満腹かを虎のプロパティに記録するのではなく、その日に食べた肉の量を記録して、10kgに満たなければ空腹であると判断するようにしても、あなた自身はそれを気にする必要はない。

このことにより、あなた自身は「虎」の細かいことは気にせずに「飼育員の業務」の章の執筆に専念することができる。

このような状態を内部実装がカプセルの中に隠蔽されると見立ててカプセル化と呼ぶ。

共通化

虎ではなくサイE, Fが増えたとしよう。以下のような対応が可能である。

動物

動物は空腹になったり満腹になったりする。

餌のやり方

動物に対し餌を用意する。
動物の檻に用意した餌を置いてくる。
動物は満腹になる。

虎は動物である。

餌の用意

虎に対し肉10kgを用意する。
虎用の肉10kgを1kgごとに切り分ける。

サイ

サイは動物である。

餌の用意

サイに対し草を10kg用意する。(切り分けなくて良い)

飼育員の業務

A, B, Cは虎である。
E, Fはサイである。

動物A, B, C, E, Fに餌をやる。

「虎」と「サイ」の共通点である「動物」という性質(分類)を記述することにより、虎とサイについては相違点である餌の用意方法だけを記述すれば済むようになっている。

そして、餌をやる時も「虎」と「サイ」について別々に記述せず「動物」とひと括りにして餌をやることができるのだ。

用語解説2

  • サブクラス(subclass): 分類上、あるクラス(分類)をさらに細かく分類した下位の分類にあたるクラスのこと。上記では「虎」「サイ」が「動物」のサブクラスに当たる。派生クラスという呼び方もある。
  • スーパークラス(super class): サブクラスの反対。上記では「動物」が「虎」「サイ」のスーパークラスに当たる。基底クラスという呼び方もある。スーパーとついているが、サブクラスの方が多機能である。
  • 継承(inheritance): サブクラスはスーパークラスの性質を継承しているという、オブジェクト指向や型付けにおけるルール。上記では「虎」「サイ」が「動物」(の一種)であると宣言することで実現している。
  • 多態性(polymorphism): 同じクラスなのに違う振る舞いをすること。上記ではA, B, Cは虎でE, Fはサイだが全て動物であるという点では共通している。「餌をやる」という操作に対して、動物であるという点ではA, B, C, E, Fで共通しているにもかかわらず、A, B, Cには「虎の餌のやり方」が実施され、E, Fには「サイの餌のやり方」が実施される。

リスコフの置換原則

サブクラスのインスタンスは必ずスーパークラスの性質を備えているべきであり、スーパークラスのインスタンスと置き換えて使用することができるという「継承」の原則論。

上記でいうなら「動物X」と書かれているところがあれば、「虎A」や「サイF」で置き換えてもマニュアルとして意味不明や実施不可能にならないということ。

これを満たさない継承はおそらくまともに動作しないのでやってはならない。

弊害

プログラミングミスの話をしよう。

プログラミングにおいては便利に書けるというのも大事なことだが、ミスによるバグをなくすというのも大事な話である。プログラミングで大変なのはプログラムを書く工程ではなく、バグを探すデバッグ工程であるという話もあるくらいである。

手続き型プログラミングと呼ばれる旧来のスタイルよりも、ミスは減ったがそれでもプログラミングにおける問題点を完全になくすことはできなかった。概要で述べたようにオブジェクト指向は全てを解決する魔法ではない。

以下ではオブジェクト指向が批判される原因となるミスについて、上記の例を引き継いで解説しようと思う。

別のところでも書いたが、単純化して説明するので「そんなミスする奴いねーよ、バーカ」とか思ってしまうかもしれない。しかし、日々繰り返したり、他のことと組み合わさって複雑になったりすると実際に起きてしまうのだ。

状態変化

なお、以下では虎が死亡するが、非実在虎であり動物虐待ではない。異論は認めない。

以下のルールを追加する。

虎は、満腹時に餌を与えると過食により死亡する。

なお、虎Cが死亡するとあなたは監督責任を問われてクビになる(プログラムの異常終了)。


動物園は発展し、あなたは出世して部下に各動物のマニュアル作成を任せ、自身は「飼育員の業務」の章の執筆に専念できるようになった。そんな折、「猛獣ショーをやるぞ」という園長の掛け声のもと手順書が以下のように変更された。単純化のためサイは来なかったものとする。

飼育員の業務

虎Cを猛獣ショーに出演させる。
虎A, B, Cに餌をやる。

ところが、猛獣ショー開演当日の閉園後、虎Cが死亡したという報告が届き、あなたはグビになった。

どうしてこうなった。

実は部下に任せていた「虎」の章は以下のようになっていたのだ。

虎は空腹になったり満腹になったりする。
虎は、満腹時に餌を与えると過食により死亡する。

餌のやり方

虎に対し肉10kgを用意する。
虎用の肉10kgを1kgごとに切り分ける。
虎の檻に切り分けた肉を置いてくる。
虎は満腹になる。

猛獣ショー

虎が芸をするごとに褒美として肉を1kg与える。
虎が満腹になったら終了。

猛獣ショーで虎Cはご褒美をもらって満腹になっており、この状態で虎A, Bと共に餌を与えられたため過食により死亡したのだ。

このような不幸な事故が起こった原因としては色々考えられるが、一つはマニュアルにおいて虎Cと書かれているだけでは虎Cが空腹なのか満腹なのかわからないということが挙げられる。つまり虎Cというオブジェクトに空腹という状態と満腹という状態両方が存在しうることが問題なのである。

またカプセル化により「猛獣ショー」のメソッドの中身を意識しなくなったことも原因の一つといえるかもしれない。

この問題を回避する方法は一通りではないのと、方法(参照透過)によっては空腹な虎が異次元空間に消えたりするのでここではこれ以上深入りしない。

オブジェクト指向ではオブジェクトの状態が変化していくことが前提なので、参照透過とは相性が悪いとされている。

不適切な抽象化

抽象化・共通化は利点であるが、共通化した部分に個別に変更する部分が生じた場合、また非共通化することになる。

サイが登場した例でいえば、

虎は肉食獣なので逃走のリスクを下げるため、虎の檻だけ扉を二重にしたくなったとする。檻の出入りは「動物」のメソッドで共通化しているので、虎の檻の出入りの手順だけを変更しようとすると、せっかく共通化した「檻の出入り」の部分を「虎」と「サイ」で別々に書き直さなければならない。

継承によるプログラムの部品化はオブジェクト指向の特色とされている。確かに、各プログラミング言語の標準ライブラリレベルで十分な時間と人手をかけて検討されテストされた継承であれば、オブジェクト指向の利益を最大限に享受できるだろう。しかし、末端のプログラマーがその場の思いつきで共通部品化したものについては継承により予期せぬ不具合を引き起こすと言われており、言語仕様上は継承をサポートしていても積極的に継承を利用することは勧めていない場合もある。

おまけ: 宣言型プログラミング

関数型プログラミングでは宣言型プログラミングという、ものごとの関係性を「宣言」する形でプログラミングするスタイルが奨励されている。上記の例にあわせて書くと以下のような雰囲気になる。

  1. 業務終了後、全ての虎は満腹になっていなければならない。
  2. 虎を死亡させてはならない。
  3. 当園には虎A, B, Cがいる。
  4. 虎は空腹か満腹かのいずれかである。
  5. 虎に餌を与えると満腹になる。
  6. ただし満腹の虎に餌を与えると死亡する。

オブジェクト指向では、「虎A, B, Cに餌をやる。」という飼育員への作業命令が主文であったのに対し、宣言型プログラミングでは「全ての虎は満腹になっていなければならない。」という「目的」の「宣言」が主文となっていることに着目したい。また、他の文も定義を「宣言」しているだけで飼育員に「何をしろ」とは言っていないことにも目を向けるべきである。

さて、このマニュアルを受け取った飼育員はどのように行動するのか。

  1. 全ての虎は満腹になっていなければならない。 → 「全ての虎」って何?
  2. 当園には虎A, B, Cがいる。 → ああ「虎A, B, C」のことね。
  3. 虎に餌を与えると満腹になる。 → 満腹にするには「虎A, B, C」に餌をあげればいいのね。
  4. ただし満腹の虎に餌を与えると死亡する。虎を死亡させてはならない。 → おっと、満腹の時には餌をあげないようにしないと。
  5. 虎は空腹か満腹かのいずれかである。 → なるほど。満腹でない虎、つまり空腹の虎にだけ餌をあげればいいのか。

ということで、この飼育員は虎A, B, Cのうち空腹な虎にのみ餌をやるという行動を取る。実際のプログラミング言語処理系はここまでは忖度してくれない。

「目的」と「定義」だけ「宣言」すれば実際に作業内容を指示しなくても、自動的に動作が組み立てられるという優れたプログラミングパラダイムであるという主張がある一方で、定義から実際の動作がどのようになるのか想像しづらい場合が多いという批判もある。

関連項目

  • オブジェクト
  • インスタンス
  • クラス / 型付け
  • モジュール
  • インターフェイス(ダイヤモンド継承)
  • メソッド / プロパティ
  • ポリモーフィズム
  • プログラミングパラダイム
    • 手続き型プログラミング
    • 関数型プログラミング
  • C++ / Java
  • プログラミング関連用語の一覧

おすすめトレンド

ニコニ広告で宣伝された記事

記事と一緒に動画もおすすめ!
☆くろさや☆[単語]

提供: 奥沢美咲

もっと見る

急上昇ワード改

最終更新:2025/12/09(火) 15:00

ほめられた記事

最終更新:2025/12/09(火) 15:00

ウォッチリストに追加しました!

すでにウォッチリストに
入っています。

OK

追加に失敗しました。

OK

追加にはログインが必要です。

           

ほめた!

すでにほめています。

すでにほめています。

ほめるを取消しました。

OK

ほめるに失敗しました。

OK

ほめるの取消しに失敗しました。

OK

ほめるにはログインが必要です。

タグ編集にはログインが必要です。

タグ編集には利用規約の同意が必要です。

TOP