IT・パソコン関連

オブジェクト指向とは?初心者でもわかりやすく徹底解説!

更新日:

オブジェクト指向

※本記事には広告(アフィリエイトリンク)が含まれます。

プログラミングをする上で、様々な書き方・概念がある中、必ず直面するのが「オブジェクト指向」というものです。

Java・Ruby・Python・C#等々言語に関係無くオブジェクト指向の概念は存在し、しかも急にカプセル化とかクラスとか言われてもイマイチピンと来ないですよね。

本記事では、オブジェクト指向とは一体何なのか?というところを例を用いて初心者でもわかりやすく徹底的に解説しました。
ぜひ、プログラミングを書く上での参考にして貰えると嬉しいです。

スポンサーリンク

【そもそもオブジェクト指向って?】

定義としては、ソフトウェア工学構想の一つであり、ソフトウェア設計及びプログラムを記述する際に使用される考え方や概念のことを表すとされています。

つまるところ、プログラミングをする上で絶対にこの書き方で遂行しなければならないというルールではなく、このような考え方でプログラミングをしていく方法もありますよというものです。

実際に色々なプログラマーの方を見ていると、

  • 「自分は絶対にオブジェクト指向でなければ嫌だ」
  • 「いやいや手続き型プログラミングだろう」
  • 「関数型プログラミング一択だよ」

等々、派閥みたいな事象にまで発展しております。笑

熱い議論がそこにあるわけです。

株式投資で言うところのテクニカル派(チャート重視)とファンダメンタル派(企業業績重視)みたいな感じですね。(わかりにくい例であれば申し訳ありません。)

ただ、「概念」である以上オブジェクト指向の説明は人によって変わってきたりします。

例えば「果物」という概念に対して、「甘い食べ物」と答える人もいれば、「樹木になるもののみを指す」と答える人もいたりと、各々が持っている「概念」に対しての考え方は千差万別です。

【オブジェクト指向が難しいと感じる理由】

上記でも説明しました通り、オブジェクト指向は「概念」となります。

ゆえに、これから「概念」の説明をしようとしていると考えたら何やら難しい感じがしませんか?

概念を理解しようとするのは難しいもので、理解したと思い込んでもやはりどこかでずれが生じたりするものです。

そもそも非常に曖昧な存在を完璧に理解する姿勢自体が正しいとは言い切れない部分もありますので、今回はオブジェクト指向という概念の大枠を掴み、理解する、ことを目標として話を進めたいと思います。

【オブジェクト指向のイメージ】

オブジェクト指向はモノを「作成」していき、それを「操作(役割)」するというイメージを持ちます。

わかりやすい例だと車です。

私たちは何気なく車に乗り、運転方法を教習所で学び、それ以降はあらゆる道路を車で走りますよね。

ですが、物凄い距離を走っているドライバーでさえ、車がどのような仕組みでエンジンが掛かり、そのエンジンがどのような仕組みで車を動かしているのかはほとんど知りません。

シリンダーの中でピストンが往復し、その往復運動をクランクシャフトで回転運動に変えて動力となるので車が動作する。

ということは知っていてももちろん良いには良いのですが、車を運転する上で知る必要は基本ありません。

「車の仕組みを作成」することと、「車を操作する方法」を切り分けているためこのようなことが起こるわけで、オブジェクト指向はまさにこの考え方であります。

【オブジェクト指向のメリット】

短いシンプルなコンテンツを作成してそれっきりというコンテンツの場合は、手続き型プログラミングで十分となりますが、複雑なコーディングだったり同様の記述が多数存在する場合だと厳しくなると思います。

先ほどオブジェクト指向は「モノ」と「モノの操作(役割)」に分けられると話しました、プログラム上で「モノ」が1個しか無い場合は特に意識する必要も無いのですが、例えば100個あったりしたらどうでしょうか?

プログラマーの方であれば重々承知だとは思いますが、実際にプログラミングをしていくと「モノ」の数は膨大になっていきます。

わかりやすい例

「モノ」の数が膨大になりがちなゲームコンテンツなどを作成するときには威力を発揮すると思います。

例えばRPGゲームを作成する場合、剣を持つキャラクターが100人いるとしましょう。(「剣を持つ」という部分のコードは全て同じとする。)の中から選べるとしたときに、100人全てを手続き型プログラムで書こうとすると膨大なコード数とあまりにも被る無駄なコードが生まれてしまいます。

そこで、「剣を持つ」という部分を定義として作成してしまえば、100人のキャラクターの「剣を持つ」というコード部分は全てその定義を引っ張ってくるだけど済むことになります。

仕様変更や複数人開発にも適している

もし「剣を持つ」部分に変更が起きた際も、100人分を変える必要は無く、「剣を持つ」定義部分を変更してしまえば済むので、仕様変更の点から見ても作業効率が上がります。

変更に対して柔軟に対応できるという点は魅力的ですし、そもそも仕様変更が起きやすい部分をあらかじめ抽出するという選択を取るのも賢いコーディングです。

また、複数人数で対応している時、例えば100人分のキャラクターを分担して開発しているとします。

オブジェクト指向で書いた場合、「剣を持つ」という定義は、作成者だけが知っていれば問題ありません。

他の開発者は、「剣を持つ」という根元を軸に、「銀髪」「女性」「黒い服を着ている」等の枝葉の部分だけを開発すれば良いことになります。

わざわざ「剣を持つ」という部分の中身に関して理解しなくても作業を進めることができますので、全体の作業効率も間違いなく上がります。

リスク観点のメリット

上記のように作業を分担し、100人分は同一のモノを使っているということはリスク観点から見てもメリットがあります。

手続き型で「剣を持つ」コードを100人分書き、それぞれに別の人が対応して開発している場合、「剣を持つ」部分を書き換えてしまう恐れがあります。

そうなってしまいますと、AのキャラとBのキャラで剣を持つ定義に差分が生まれてしまい、Bのキャラだけが動作不具合を起こすという事態を引き起こしてしまいかねないのです。

リスクを管理し、見える化しやすいという点でもオブジェクト指向で書くメリットと言えます。

【オブジェクト指向の用語】

オブジェクト指向とは?というところと、オブジェクト指向で書くメリットとは?というところ説明しましたが、いよいよもう少し深いところに入りたいと思います。

「モノ」とか「操作(役割)」と上記では書いてきましたが、オブジェクト指向ではそれぞれに対してちゃんとした用語が用意されております。

以下では、その用語に関して説明していきたいと思います。

オブジェクト(Object)

散々オブジェクトオブジェクトと書いてきたので今更感はありますが、「モノ」の部分に当たる用語がオブジェクトとなります。

先ほどの例で言いますと、「車」がオブジェクトになります。

世の中を見渡すとオブジェクトとなる対象は無数に存在し、例えば「人間」、「テレビ」、「パソコン」、「スマホ」、「飛行機」どれもオブジェクトとなります。

「車」というオブジェクトを見たときに、でも車には色んな部品やらが付属していますよね?

タイヤや、窓、ワイパーにエンジン、それらを全て設計図通りに兼ね備えたのが「車(オブジェクト)」であり、その車が走ったり停車したりドリフトしたりするわけです。

クラス(Class)

オブジェクトの説明で、設計図通りに組み立てたのが「車(オブジェクト)」と書きましたが、クラスはその「設計図」の位置に当たります。

計4個のタイヤをこの位置に付ける…窓はこのサイズで…ボディの色は白色で…等々皆さんが想像するような設計図です。

プロパティ(Property)

車(オブジェクト)には、窓やタイヤ、ワイパーにエンジン…が付属していると書きました、プロパティはこの付属部品の部分を指し示します。

直訳では「属性」と表現されます。

メソッド(Method)

車(オブジェクト)の動作(処理)のことを指し示します。

「走る」「止まる」「ドリフトする」等々がメソッドに当たります。

以上のように、細かく説明しましたが全体を通して一連付けますと、

という流れになります。

実際にコードを書くとどうなる?

オブジェクト指向で使われる基本用語に関しては説明しましたが、では「実際にコードを書こうとしたらどうなるのか」という点を解説したいと思います。

「オブジェクト・クラス・プロパティ・メソッド」の関係式はざっくりと下記の形になります。

よりわかりやすく、具体的に車で置き換えて記述するとこうなります。

class Car {

 String window; //窓

 String tire; //タイヤ

 Int speed; //速度

 void start() { System.out.println(“発車”); }

}

インスタンス(Instance)

インスタンスもオブジェクト指向で書く上では必須の項目となります。

インスタンスは直訳で「実体」を表します。

急に「実体」と言われても何のことやらとなるかとは思いますが、オブジェクトが何かを作成することをインスタンス化と言います。

クラス名 参照変数 = new クラス名();

という形で作成します。

【オブジェクト指向三大要素】

更に、オブジェクト指向を語る上で重要となる三大要素が存在します。

それが、「カプセル化」「継承」「ポリモーフィズム」と呼ばれるものなのですが、初めて聞く人にとってはさっぱりかと思います。

 

カプセル化→あー何かカプセルっぽくまとめるのかな?

継承→あー何か引き継ぐのかな?

ポリモーフィズム→?????日本語でお願いします。

 

急に言われてもこうなるのが当然かと思います。

そこで、オブジェクト指向で重要なこれら三大要素をひとつずつ解説します。

カプセル化

簡単そうに見えて非常に重要かつ難しいのがカプセル化です。

カプセル化は抽象化であり、無駄を省くために洗練化させて分かりやすくすることです。

記述の中で、互いに関連するデータの集合とそれらに対する操作をオブジェクトとして一つの単位としてまとめ、外部に対しては必要な情報や手続きのみを提供しつつ、外部から直接参照や操作をする必要の無い内部に関しては隠すことを表します。

 

細かく紐解くと、オブジェクトが持つプロパティやメソッドの中で、他のオブジェクトから直に参照や操作をする必要の無いものは隠されるということであり、万が一使用する場合は用意された手続きを踏んで利用するということです。

先ほどの例で照らし合わせますと、オブジェクト(車)が持つプロパティ(窓やエンジン)やメソッド(走ること)の中で、他のオブジェクト(例えば飛行機)から直に参照や操作をする必要の無いもの(例えばエンジン)の内部の状態や構造は隠される。ということになります。

 

カプセル化をすることは、作業を効率化させる上で非常に重要です。

上記のエンジンに関して、中の仕組みまで理解しなくてもエンジンを動かす手続きさえ知っていれば、動作部分のコード開発者は作業できるわけです。

 

先ほど、「剣を持つ」という特徴を持つRPGキャラ100人も、全てにその特徴を記述するのではなく、「剣を持つ」という定義だけあれば、あとはそれを呼び出すだけで、その他の「銀髪」「女性」と言った枝葉の部分をコーディングするだけで良いという話をしましたが、まさにこの「剣を持つ」という部分が「カプセル化」なのです。

「銀髪」部分をコーディングする人にとっては、「剣を持つ」という中身のコーディングを知る必要は一切無く、むしろそれが見えてしまっていると理解しなければならないという作業に無駄が発生してしまうため、内部を秘匿化しておくことが大切なのです。

これが抽象化であり、無駄を省くために洗練化させて分かりやすくすること。なのです。

ただ、カプセル化をする上で重要なのは、「役割を一つにする」ことです。

「剣を持つ」という特徴の中で、「たまに斧を持つ」とか、「自動回復する」とかを入れてしまうと、分かりやすく洗練されたカプセル化とはほど遠い存在に成り下がってしまいます。

カプセル化では、「守備範囲を広げる」ことではなく「明確で分かりやすい」ということが何よりも大切なのです。

継承

ロマンシングサガ2をやっている人にはお馴染みの継承(え)。

親の機能を受け継ぐというのは継承の本来の意味ではありますが、オブジェクト指向では特定のオブジェクトの機能を引き継いで使用することを表します。

類似したオブジェクトをたくさん作る時に、プロパティ・メソッドを毎回コーディングするのは時間的にもコード数的にも無駄なので、元となる親から引っ張ってきてラクしましょう。ということです。

例えば「乗り物」という親要素がいたとします。

「車」や「バイク」、「自転車」を説明しようとした時に、毎回「乗り物」コーディングを記載していたらコード数が増えてしまいます。

そこで、「乗り物」という親要素から継承することで、毎回その部分を書く必要は無くなります。

わーい!楽だ!継承使いまくろう!と思う部分はあるのですが、注意点があります。

それは継承を多用することで、関係性が逆転した記述を書いてしまう人がいることです。

乗り物と車の関係は、部分集合の関係になります。

部分集合

上記の図で言うとBが乗り物でAが車です。

これが逆転することは有り得ません。

何故なら、車は乗り物ですが、乗り物だからと行って車とはならないからです。

乗り物はバイクもあれば飛行機もあります。

一見単純で、それは当たり前だろう!とも思うのですが、コーディングをしている上でこの関係を逆に書いたりして継承してしまっている人が少なからずいます。

「親から子へ」という関係を常に意識して継承をするようにしましょう。

ポリモーフィズム

日本語でよろしくのポリモーフィズムの登場です。

英語で書くと「Polymorphism」で、直訳は「多様性」です。

例えば「エンジンの仕組み」は、決して車を動かすだけのものではありません。

動力という観点で、あらゆるものに応用が効いたりします。

この考え方は、再利用という点で継承に近い部分はありますね。

ただ、継承ばかりでは同じ振る舞いをするプログラムしか作成できないですが、ポリモーフィズムでは、同じ振る舞いをする根幹部分は共通ですが、目的に合わせて違う振る舞いに変えるという枝葉の部分での調節が可能です。

このように、ポリモーフィズムではより柔軟に振る舞いを引っ張ってくることが可能です。

ポリモーフィズムに関しては、言葉では理解しにくい部分がありますので、実際にコーディングしていく上でピンと来る部分もあるかと思います。

ここでばっちりと理解していなくても不安になる必要はありません。

以上で、オブジェクト指向とは?メリットとは?用語とは?をざっくり説明しました。

本記事では、オブジェクト志向という概念の大枠を捉える部分に焦点を当てましたが、具体的なコーディングの話も無いと分かりにくい部分もあるかと思いますので、別記事にてコーディング部分を説明したいと思います。

JavaScriptで書くオブジェクト指向|プロトタイプとクラス構文の基本

※この章は2026年10月6日時点の情報です。

ここからは、ここまでの考え方をJavaScriptで実際に書くとどうなるかを見ていきます。JavaScriptはもともと、クラスではなく「プロトタイプ」というしくみでオブジェクト同士が機能を受け継ぐプロトタイプベースの言語です。ECMAScript 2015(ES2015、ES6とも呼ばれます)でclass構文が加わりましたが、MDNの解説どおり、クラスも内部ではプロトタイプのしくみの上に成り立っています。

オブジェクト・プロパティ・メソッド

いちばん手軽なのは、波かっこでオブジェクトを直接書く方法(オブジェクトリテラル)です。nameやmaxSpeedがプロパティ、describeがメソッドにあたります。

const car = {
  name: "車A",
  maxSpeed: 180,
  describe() {
    return this.name + "の最高速度は" + this.maxSpeed + "km/hです";
  },
};
console.log(car.describe()); // 車Aの最高速度は180km/hです

クラスとインスタンス(ES2015以降の書き方)

同じ形のオブジェクトをたくさん作るなら、設計図となるクラスを書き、newでインスタンスを作ります。constructorはインスタンスを作るときに呼ばれ、プロパティの初期値を決めます。

class Car {
  #fuel = 100; // # を付けたプライベートフィールド(外から直接さわれない)

  constructor(name, maxSpeed) {
    this.name = name;
    this.maxSpeed = maxSpeed;
  }
  describe() {
    return this.name + "の最高速度は" + this.maxSpeed + "km/hです";
  }
  get fuel() {
    return this.#fuel;
  }
}

const a = new Car("車A", 180);
const b = new Car("車B", 160);
console.log(a.describe(), b.fuel); // 100

#fuelのように名前の前に#を付けると、クラスの外から直接読み書きできない「プライベートフィールド」になります(ES2022で標準化)。これがJavaScriptでのカプセル化の書き方です。

継承とポリモーフィズム

extendsで親クラスを受け継ぎ、superで親の処理を呼び出します。子クラスで同じ名前のメソッドを書き直す(オーバーライドする)と、同じdescribe()の呼び出しでも中身が変わります。これがポリモーフィズムです。

class Truck extends Car {
  constructor(name, maxSpeed, load) {
    super(name, maxSpeed); // 親クラスのconstructorを呼ぶ
    this.load = load;
  }
  describe() {
    return super.describe() + "(積載量" + this.load + "t)";
  }
}

for (const v of [new Car("車A", 180), new Truck("トラックB", 100, 4)]) {
  console.log(v.describe());
}
オブジェクト指向の用語JavaScriptでの書き方
クラス(設計図)class Car { ... }
インスタンス(実体)new Car("車A", 180)
プロパティthis.nameなどに値を入れる
メソッドクラスの中にdescribe() { ... }と書く
継承extendsとsuper
カプセル化#付きのプライベートフィールド
ポリモーフィズム子クラスでメソッドを書き直す(オーバーライド)

thisは「どう呼び出されたか」で中身が決まります。const f = a.describe; f();のようにメソッドを取り出して呼ぶと、thisがcarを指さなくなるので注意しましょう。アロー関数は自分のthisを持たない点も、つまずきやすいポイントです。

[PR]

ゲーム好きが読んで得する2選

遊ぶ・仕事にする・英語で楽しむ。“好き”を1歩先に進めるならこの3つ。

ファミキャリ(ゲーム業界の転職相談)

好きなゲームを「仕事」にするなら、まず無料相談

  • ゲーム業界に特化した転職エージェント
  • 未経験から狙える求人や、自分の市場価値がわかる
  • 相談は無料。話を聞くだけでもOK

ゲーム業界の求人を無料で見てみる

スタディサプリENGLISH

海外ゲーム・配信を字幕なしで楽しむ英語力を

  • 1回3分から、スマホでゲーム感覚で続けられる
  • 海外版の最新情報や英語実況が分かるようになる
  • 無料体験から始められる

スタディサプリENGLISHを無料で試す

-IT・パソコン関連
-, , ,

Copyright© MediaTrendy|メディトレ , 2026 All Rights Reserved.