質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • C

    3686questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    3450questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • オブジェクト指向

    284questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

オブジェクト指向って何が凄いんですか??

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 9
  • VIEW 1,795

strike1217

score 554

オブジェクト指向って何が凄いんでしょうか??

どういった経緯で誕生したものなんでしょうか?

例えば、CとC++が一番わかりやすいですかね。
C++ではクラスを作ることができます。

win32 APIを使ってGUIのプログラミングをしていた時に、switch文に別の世界のようなものを埋め込むことができて便利だなぁと思ったことがあります。
しかし、それ以外で「ほぉ~~。こんなに便利なのか!」といった場面がありませんでした。

オブジェクト指向でプログラミングすることのメリットを教えてください。

例えば、LinuxカーネルはC言語でありながら無理やりオブジェクト指向を実現したような記述の仕方をしているようです。
なぜ無理にオブジェクト指向に拘ろうとするんですかね??
オブジェクト指向プログラミングとそうでないプログラミングの違いやメリットデメリットがイマイチわかりません。

オブジェクト指向と10年戦ってわかったこと
初心者向けに徹底解説!オブジェクト指向とは?
オブジェクト指向がわからない! そんなあなたの脳味噌をオブジェクト脳にする準備体操

オブジェクト指向の本質は何ですか??
classですかね?

オブジェクト指向プログラミング(Object Oriented Programming: OOP)とは、プログラムを手順ではなくて、モノの作成と操作として見る考え方だ。オブジェクトとは「モノ」を意味する。
「テレビ」というモノを操作するとき、中でどういうプログラムが動いているか知る必要はない。リモコンで操作すれば、動く。
「こういう”モノ”を作りましょう」「そして、その"モノ"を使いましょう」というのがオブジェクト指向という考え方だと思っていい。なぜモノを作っておくと便利なのか?

普通の関数とかではダメなんでしょうか???

あ、それとpythonはオブジェクト指向なんでしょうか??

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ozwk

    2017/10/30 16:32

    https://qiita.com/hirokidaichi/items/591ad96ab12938878fe1 は読みましたか?

    キャンセル

  • strike1217

    2017/10/30 16:34

    初めて見ました。この記事!見てみます。

    キャンセル

回答 5

checkベストアンサー

+10

例えばAさんの書いた、以下のような関数だけで書いたコードがあったとします。

int globalA = 0;
int globalB = 0;
int globalC = 0;

void procA(int a) {
  globalA = a;
}
void procB(int b) {
  globalB = b;
}
void procC(int c) {
  globalC = c;
}

procA(10);
procB(12);
procC(20);

うん、まあ意味はともかく、名前と変数が一致しているのでprocAはglobalAに対する作用を持っていて、といった関連付けが「雰囲気で察知」、「コードを見ればはっきり判別」可能です。ではこのコードをヘッダと分けましょう。

// test.h
#ifndef __TEST_H
#define __TEST_H

extern int globalA = 0;
extern int globalB = 0;
extern int globalC = 0;

void procA(int a) {
  globalA = a;
}
void procB(int b) {
  globalB = b;
}
void procC(int c) {
  globalC = c;
}

#endif
// test.c
#include "test.h"

procA(10);
procB(12);
procC(20);

test.hをincludeして使うと、procA、procB、procCという名前だけがコードに残りました。あとから見ると「procAは多分globalAに対して作用するんだな」とふんわりした想像になります。

ここでアホなプログラマ仲間Bさんが加わり、procAの処理を自分の都合で書き換えてしまいました。

void procA(int a) {
  globalA = a;
  globalC--; // !!!???
}


さてAさんはprocAを実行したときにどう思うでしょう。「procAって名前なのにglobalCを書き換えてんじゃねぇよ!」とキレるでしょう。最悪AさんはglobalCが書き換わっていることに気付きません。このまま作業が進んでいくと、間違いなくバグの温床になります。関数だけで実装を行う場合、「関連付けがはっきりしていない」ことが致命的なバグを生むことが考えられます。オブジェクト指向の無い世界では、Bさんのように雰囲気や暗黙の了解を無視して「影響を及ぼす範囲を無視しためちゃくちゃな実装が言語的には許されている」ことが問題なのです。これは「故意」であれ「過失」であれ同じ問題です。うっかり「変数名の打ち間違い」で全く関係ないグローバルな変数を書き換えてしまう事故も考えられます。

ここで「オブジェクト」という単位が生まれます。関数と変数に明確な「関連付け」がされます。

class A {
public:
   int valueA;
   void proc(int value) {
      this->valueA = value;
   }
};
class B {
public:
   int valueB;
   void proc(int value) {
      this->valueB = value;
   }
};
class C {
public:
   int valueC;
   void proc(int value) {
      this->valueC = value;
   }
};

これならクラスAが操作できるのはクラスAが持っている変数だけで、外に影響はでません。クラスAの中でクラスBを書き換えようとしてthis->valueBと書いてもコンパイルエラーで書くことができません。オブジェクト指向はこういった「メソッドの及ぼす作用の範囲の明確化」が一番のメリットだと考えています。

python自体はオブジェクト指向とは言わないと思いますが、classを使ってのpythonコードはオブジェクト指向と言えます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/30 16:54

    >関数だけで実装を行う場合、「関連付けがはっきりしていない」ことが致命的なバグを生むことが考えられます。

    > オブジェクト指向はこういった「メソッドの及ぼす作用の範囲の明確化」が一番のメリットだと考えています。

    おお!!なるほど!!
    大変分かりやすいですね!!

    キャンセル

  • 2017/10/30 16:57

    ちょっと中盤の文書を修正しました。「事故を防ぐ」といった点においても、重要な意味を持ちます。

    キャンセル

  • 2017/10/30 16:59

    関連付けというのが非常に大事な事なんですね!!
    これからは意識してみます!

    キャンセル

  • 2017/10/30 17:04

    オブジェクト指向とそうでない言語では、オブジェクト指向で実装するプログラマの方が多いんですかね??

    キャンセル

  • 2017/10/30 17:06

    機械の中の組込系プログラミングであれば「容量」や「使える言語」の縛りで関数だけでやっている人もいるかと思いますが、今の御時世、アプリケーションを作るのに関数だけでやってる人間はほぼ絶滅しているかと思います。というか、できればそのような人と一緒にアプリケーション開発はしたくないですね。

    キャンセル

  • 2017/10/30 17:08

    >アプリケーションを作るのに関数だけでやってる人間はほぼ絶滅しているかと思います。
    げげ!!
    そうなんですか。
    では、C++の知識は必須になってきますね!

    大規模なプログラムであれば、あるほどオブジェクト指向で実装した方が良いのですね!!

    キャンセル

  • 2017/10/30 17:13

    もちろん個人での開発は勝手に関数だけでやってください、でいいですけど、業務でのアプリケーション開発やるなら上記のような事故は防ぎたいものです。自分のせいで自分が苦しむならいいですが、他人のせいで自分が苦しむのは問題があるかと思います。昨今の主流なアプリケーション開発用の言語やツールはみんなオブジェクト指向ですよ。

    キャンセル

  • 2017/10/30 21:08

    「大規模または数人で関わるプログラムの場合にオブジェクト指向は威力を発揮する」
    大変分かりやすかったのでベストアンサーにさせてもらいます。

    キャンセル

+7

C でやるとわかるのですが、データを簡便に処理するために構造体を作り、その構造体に対して何らかの処理を行う関数を作ることがあります。
ここで問題になるのが、構造体と関数とを結びつけるものが「言語的には」存在しないことです。対応はあくまでもプログラマがその責任においてやらねばなりません。

でも、古くから「アルゴリズム+データ構造=プログラム」といわれるように、アルゴリズムとデータ構造とは不可分の関係にあります。構造体においても同じで、あるデータ構造があったら、それに対応する処理は、ひとまとめになっているべきだ、という考え方が出てくるのは当然のことでした。
それを推し進めた結果が、C++ におけるクラスの考え方のもとになっています。
※実際、C++ は「構造体がメンバ関数を持てる」のです。C++ では構造体は「標準のアクセス制御が public であるクラス」と同義となっています

クラスとは、単体で完結したプログラムの部品です。複雑な機械が、分解してみると小さな部品類(歯車だったりバネだったり)の組み合わせであるように、小さな完結したプログラムであるクラスという部品を組み合わせて、複雑なプログラムを作ろうという発想です。
それぞれのクラスは完結しているから、不必要な情報を外部に漏らしません(アクセス制御による情報の隠蔽)し、それが行うべきことはクラス自体が知っています。
部品を使う側からしてみれば、部品の中身の細かい動作は知る必要がなく、ただ入出力さえ分かっていればよいのです。
※例えば、テレビのリモコンでテレビのチャンネルを変えることはできますが、「なぜできるのか」なんて知らなくても使えますでしょ?

まあ、これはオブジェクト指向プログラミングの現実から見た答えです。
もともとのオブジェクト指向はもう少し概念的なものが出てきます。ことにオブジェクト同士が協調するために「メッセージ」をやりとりする、というのが、なかなかに実際のプログラミングではでてこない部分ですね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/30 16:28

    >古くから「アルゴリズム+データ構造=プログラム」といわれる
    え!そうなんですか!

    構造体と関数とを結びつけるものがオブジェクト指向の本質なんですかね?

    キャンセル

  • 2017/10/30 16:42

    > 構造体と関数とを結びつけるものがオブジェクト指向の本質なんですかね?

    まさにそれを体現したかのようなオブジェクト指向環境もいくつかあって、たとえばPerlでは、もともとあったモジュール機構に、「bless」という「ハッシュとメソッドを結びつける」仕組みだけを取り入れて、オブジェクト指向として使えるように仕立てています。

    https://qiita.com/tadnakam/items/485fe6fd1cf79f3cb97c

    キャンセル

+2

凄いかどうかはわかりませんが…。

オブジェクト指向でプログラミングすることのメリットを教えてください。

役割分担が明確になることではないでしょうか。
例えばあるボタンのクラスを作ったら、そのクラスはボタンを扱う専用の処理になるわけです。
ラベルもコンボボックスも関係なく、純粋にボタンのみ。
ボタンで不具合が起きたらそのクラスに問題があるわけで、問題の切り分けもしやすいです。

C言語でも業務に使うようなコーディングをしていると、大量の関数ができてくるわけですが、やはりある程度機能単位にファイルを分割しますよね。
これもある意味オブジェクト指向的な考えになっていると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/30 17:23

    「大量の関数ができてくるわけですが、やはりある程度機能単位にファイルを分割しますよね。
    これもある意味オブジェクト指向的な考えになっていると思います。」

    おお!なるほど!確かにそうですね!!

    キャンセル

+1

オブジェクト指向で得られる恩恵は

  • カプセル化
  • 継承
  • ポリモーフィズム(多態性)

の3つです。

(それぞれの意味はググればたくさん出てきますので割愛します。)

なお、小規模なプログラムであればそれほどの恩恵は無いように感じるかもしれませんが、大規模なプログラムになればなるほど、これらの恩恵が大きくなってきます。
プログラミングは、バグを如何に潰すか(作り込まないか)と如何に生産性を上げるかというところに掛かっています。大規模になればなるほど、また、関わってくる人が多くなればなるほどこの問題は大きくなってきます。その一つの方策(解決手段)がオブジェクト指向プログラミングになります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

オブジェクト指向には色々な流派の違いがありますが、
あくまで現時点での私の見解だと断っておきます。


どういった経緯で誕生したものなんでしょうか?

オブジェクト指向言語の一番最初の原型はSimulaで、
名前通りシミュレーションするための言語です。

「オブジェクト指向」の概念を広めたのはSmalltalk(Alto)で、
これはWindowsやMacなどの今のGUIパソコン(OS)の元祖です。


オブジェクト指向でプログラミングすることのメリット

上の経緯にあるように、Smalltalkが最初のGUI(OS)なので、
GUIに強いです。GUIを酷使するゲームなどはOOの独壇場です。
じっさい、ゲームはC#などのOO言語で作られることが多いですね。

シミュレーション、という概念は今でも有効だと思います。
ただし、現実世界をそのまま再現するのではなく、
現実から抽象したドメイン(問題領域)を再現します。

たとえばDDD(ドメイン駆動開発)というのは、
ドメインをシミュレーションするようなものです。

つまり、問題領域における概念構造を、プログラム上に再現します。
それで何がよいのかというと、変更に強いです。
とくに業務的な理由での変更に強くなります。
業務知識の構造を再現しているから、その変更も再現しやすいのです。

GUIやゲームは映像的なシミュレーション、
DDD(が使われる対象)は業務的なシミュレーションで、
ドメインこそ違うものの、OOの性質を活かしています。


オブジェクト指向の本質は何ですか?

一言で言うなら抽象化。シミュレーションも抽象化でしょう。
カプセル化、継承(委譲)、多態などの
抽象化技法によって、変更容易性が生まれます。

普通、プログラムは開発より保守の方がコストがかかるので、
変更、修正、拡張、交換などがしやすいのは大きなメリットです。
それらによってたとえば、フレームワークが作りやすくなります。

今、JavaやC#などのOO言語が一番普及しているのも、
その辺の理由が大きいと思います。

抽象化というのが抽象的で分かりにくいと思います。
抽象の反対が具象で、命令的、手続き的な手法です。

機械語、アセンブラ、C言語と高級言語化してきましたが、
機械側から人間側にさらに高水準化したのがOO言語です。

複雑、大規模、長期運用のシステムは、
具象だけで行くと人間が認識不可能になってきます。

具体的な細部の手順が一度に分からなくても、
OOではドメインモデリングで人間の知識構造を再現するので、
部分的な変更・修正・拡張がしやすくなります。


普通の関数とかではダメなんでしょうか?

今でもGoのように手続き型ベースの言語もありますし、
関数型プログラミングも有力な開発手法だと思いますが、
関数だけでOOができるかという意味ならダメです。

命令型は命令がプログラミングの単位、関数型は関数、
オブジェクト指向はオブジェクトが単位になります。

オブジェクト指向はオブジェクト=データ中心の技法であって、
メソッド=処理中心ではありません。そこが構造化技法との差です。

データを抽象化しないで、関数だけで処理を共通化していくと、
関数の引数が多いとか、インターフェイスが複雑化していきます。

デザインパターンなどは典型的なオブジェクト単位の関係です。
だから、デザパタはUMLのクラス図で解説されるのです。

このようにオブジェクトの関係、つまり責務の配分によって、
ドメインをシミュレーションするのがOOのポイントです。

最近のDDDでも、その辺りは変わらないというか、
むしろドメインモデリングへ原点回帰しています。


pythonはオブジェクト指向なんでしょうか?

OO要素も持つマルチパラダイム言語だと思います。
Rubyもそうですが、Rubyの方がOO寄り、
Pythonの方が関数型寄りに感じます。


なお今回、ドメインモデリングから
DDDへの流れを軸に語りましたが、
Smalltalk流のOOはメッセージングを重視します。

これを一言でいうと遅延結合がポイントで、
事後的な再設計を可能にする仕組みです。

どういうことかというと、後から設計を修正しやすいので、
リファクタリングなども含んだ反復的開発、アジャイルがしやすい。

つまり、XPからDDDへという、もう一方の流れがあると思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/16 11:11

    GUIに強いです。
    そうなんですか!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3686questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    3450questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • オブジェクト指向

    284questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。