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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

オブジェクト指向

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

7回答

5745閲覧

オブジェクト指向、classの便利さを教えてください。

uchi

総合スコア13

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

オブジェクト指向

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

2グッド

3クリップ

投稿2016/10/19 05:10

###前提・実現したいこと
python初心者です。
vbaやphp,matlabなどは経験がありますが、オブジェクト指向のプログラミングは初めてです。

基本的な構文は理解できていますが、classを使う意味合い、便利さがいまいちわかりません。

###コード
たとえば、名前、年齢をインプットに、それを表示させる簡単なコードを考えると、
classを使って実装すると、

class MyClass: def __init__(self, name, age): self.name = name self.age = age def show(self): print('-show name and age-') print('%s (%d)' % (self.name, self.age)) p1 = MyClass('yamada', 24) p1.show()

で、実行結果は

-show name and age- yamada (24)

となります。
一方で、同じ出力をしたい場合、関数で

def show(name, age): print('-show name and age-') print('%s (%d)' % (name, age)) show('yamada', 24)

と、より簡単に書くことができます。

###理解したいこと
上記のように、classを使って構文を書くと、どうも遠回りしているように思えてしまいます。
(__init__を使って引数を別で定義しなければいけないところ、など)

大規模なプログラミングになった場合、「複数のメソッドをclassでまとめることができ、呼び出しが簡単になる」というメリットは想像できますが、それ以外に、classを使うことによるメリット、理解の方法、classを使うことで実現できること(関数ではできない)、など、教えていただけませんでしょうか。

###すでに調べたこと
ネット上の諸先輩方のブログなどから、考え方は勉強しています。
これまでのプログラミング経験では、メソッド(関数)しか使ってこなかったため、
クラスとインスタンスの関係から概念がつかめていない為、そのあたりから勉強しています。
・クラスは設計図、インスタンスは具体例、インスタンスからクラス内のメソッドを呼び出して使う
という概念は、言葉では理解できていますが、いざ実装するとなると腹落ちしていません。

LLman, WK_ZAKK👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

こんにちは。

前者と後者は同じ出力を得ることができますが、やっていることは同じではないです。
前者はnameとageを一塊にして管理しています。後者はそれをしていません。

その差は、例えばMyClassの配列を考えると明らかです。
ここにちょうど同じようなクラスの配列を作る例がありました。
これを後者の形式で実現する場合、構造体を使ってnameとageを一塊にまとめ、グローバル関数showにそれを渡すイメージになるでしょう。

さて、異なる構造体を受け取って処理する別のshowを実装しないといけないケースもありますね。
その際にはshow構造体名()のような名前を付けることも多いと思います。
それはshow構造体名(構造体のインスタンス)の形式で呼び出します。
これは本質的にp1.show()と同じものです。

このような非常によく使われる一連のパターンをオブジェクト指向プログラミングと呼びます。
オブジェクト指向プログラミングを積極的にサポートしている言語で記述すると、より読みやすく よりメンテナンスしやすいプログラムを書くことができます。

投稿2016/10/19 07:30

編集2016/10/19 07:35
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uchi

2016/10/19 10:16

Chironianさん、ありがとうございます。 >前者はnameとageを一塊にして管理しています。後者はそれをしていません。 一塊にして管理することと、そうでないことによって、どのようなメリデメがあるのでしょうか・・・?
Chironian

2016/10/19 10:41

回答に記載した通り、例えば配列にする時に差が出てきます。 nameとageが別々ならそれぞれ用に配列が必要なので2つ必要です。 もし、nameとageだけでなくaddressとかgradeなども管理する必要が出てくると、益々配列の数が増え、メンテナンスは非常にたいへんになりますね。 一塊なら配列は1つですみます。
uchi

2016/10/20 06:09

Chironianさん、ご回答いただきましてありがとうございます。 なるほど。内容としてはわかるような気がしますが、自分自身で数をこなして実感としてもわかるように練習してみます。
guest

0

classを使って構文を書くと、どうも遠回りしているよう

OOPが真価を発揮するのは大規模なプログラムです。
たとえると、オブジェクト指向は「ウサギとカメ」のカメです。

すなわち、プログラムが大きくなってもバグによる減速が少ないので、
トータルで見れば早いという考え方です。つまり急がば回れ。


classを使うことによるメリット、理解の方法

デザインパターン」を理解すると、OOPを使うメリットも分かります。
デザパタの多くが、OOPの継承や多態を利用したパターンだからです。

もっと具体的に言うと、構造化技法では制御文の入れ子が深くなりがちですが、
if文をストラテジーなどで置きかえると整理されるので、メリットが実感できます。

投稿2016/10/19 05:39

LLman

総合スコア5592

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uchi

2016/10/19 10:13

LLmanさん、ありがとうございます。 なるほど。「ウサギとカメ」はわかりやすいです。 「デザインパターン」は初めて聞く言葉でが、少し調べて勉強してみます。 >if文をストラテジーなどで置きかえる こちらも調べてみましたが、今の私の知識では、「何やらシンプルにかけるらしい」というぐらいですが、活用できるように少しずつ勉強していきます。
guest

0

classを使うことによるメリット、理解の方法、classを使うことで実現できること(関数ではできない

Pythonにはモジュールという機能があるため、単純にモジュールに変数と関数を定義することも、クラスを作ることもできます。
どちらにもメリットがあるため、Pythonのエキスパートの人達はこれらを上手く使い分けています。

関数ではできない一番大きな機能は継承が使えない点です。
継承についてはここでは割愛しますが、非常に便利な機能です。

また、モジュールは一個のコピーしかロードされないという特性も心の隅に留めておきましょう。
(GoFのデザインパターンで言うとシングルトンとして使える)
これにより、クラスのように同じメソッドを持つが異なる属性(内部の変数等)のインスタンスを多数作成する...ということがモジュールでは難しいことも意味します。
逆に言うと、1つしか使わないオブジェクトであればモジュールに関数と変数を定義するだけ充分な場合も多いです。最たる例は、settings.pyのような設定ファイルですね。

辞書の値が長いタプルやリスト、別の辞書になるような複雑なデータ構造になった場合は、こちらもクラスを使った方が柔軟で、分かりやすいものになります。

まずは上の3つぐらいを意識し、とりあえず関数だけで書いていくスタイルでも良いかなぁと思います。
後は自分で作っていれば慣れていきますし、優秀なライブラリやフレームワークを使いながら、それを勉強するのも良いかと思います。

投稿2016/10/19 16:48

編集2016/10/19 17:01
toritoritorina

総合スコア972

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uchi

2016/10/20 06:54

toritoritorinaさん、ご回答いただきましてありがとうございます。 >とりあえず関数だけで書いていくスタイルでも良いかなぁと思います。 自分で実装する場合はまずはここからスタートしているのですが、機械学習をpythonで実装したコードなどを本で見ていると、当然のようにclassが多用されており、きちんと理解しておかないと変数がどのように渡されて、どこでどんな処理が行われているのかがわからなくなってきてしまった為、理解を深めたいと思っています。 classでしかできないこととして「継承」が挙げられていますが、classの引数にclassを指定できる、という認識であってますでしょうか。 継承ができることで、初心者からすると中身がどんどん複雑になってきて理解が難しくなってきますが、大規模プログラミングになると恩恵がありそう、ということは理解できる気がします。
toritoritorina

2016/10/20 11:17

>lassの引数にclassを指定できる、という認識であってますでしょうか。 その認識で問題ないと思います。 class ChildClass(ParentClass): のようにします。 >継承ができることで、初心者からすると中身がどんどん複雑に これは設計全般にも言えることですが、より柔軟に、より変更に強くしようとするとどうしても、一般的には複雑になります。クラスの数も増えますし、パッと見でどういう処理をしているかを追うのが少し面倒になります。 それでも尚使用するのは、それ以上のリターンがある為です。コードの再利用がしやすくなったり、修正や拡張が容易になるメリットは非常に大きいです。 ある意味では、オブジェクト指向は人間が後で楽をするための考え方です。特に、保守の段階などの後で楽をすることに威力を発揮します。
guest

0

ベストアンサー

オブジェクト指向の良い部分はいくつもありますが、わかりやすい部分を説明します。

上記のように、classを使って構文を書くと、どうも遠回りしているように思えてしまいます。

(initを使って引数を別で定義しなければいけないところ、など)

そうですね。例題の部分では関数で済むでしょうし、私もそうします。実行速度も速くなりますからね。

ところでこういうコードはどうでしょう。

print('-show name and age-') print('%s (%d)' % ('yamada', 24))

メソッドより近道ですよね。

まあ、イジワルを言ってみたのですが、メソッドがそうであるようにclassにも再利用を簡単にするという利点があります。確かに宣言が面倒だったりしますが、一度登録した引数を覚えていてくれるという機能があります。

例えば、Show干支(name, age)やIs成人(age)など同じ変数を使うメソッドをクラスとしてまとめ上げれば、引数を毎回与える必要がなくなります。

データとメソッドは不可分で、年齢のところに体重を入れても意味がないように、型だけでなく性質によって間違いがないようにできます。

また、年齢差を求めるメソッドを下記のように書けるのはうれしくありませんか?

yamada = MyClass('yamada', 24) takahashi = MyClass('takahashi', 19) yamada.ShowDist(takahashi) // yamada は takahashi の 5 才 年上 です。

まずは、変数のセットに関数をまとめたものがclassと理解すればなんとなく便利そうに見えるのでは無いでしょうか.

また、オブジェクト指向言語はまとめる機能が豊富に用意されています。メソッドなしでも書けるのと同様に使わなくても問題は無いのですが、classを含む変数のスコープを色々と選択出来るので、大きなプログラムを組むときに重宝します。

小さなプログラムでも関係性が複雑な場合、きれいに書くことが出来ます。例えば、自動で配列のサイズを拡張するスタックやリスト構造を自分で書いてみるとclassの便利さが分かるかなと思います。

投稿2016/10/19 13:05

iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uchi

2016/10/20 06:48

iwamoto_takaakiさん、 ご回答いただきましてありがとうございます。 >メソッドより近道ですよね。 この例えは盲点で、わかりやすいです。メソッドとクラスの関係性のアナロジーとして理解しました。 また、ShowDistの例について、実装をしてみました。 class MyClass: def __init__(self, name, age): self.name = name self.age = age def ShowDist(self, person): dist = self.age - person.age print('%s は %s の %d 才年上です' % (self.name, person.name, dist)) これで所望の出力ができました。 関数だけで実装する場合は、外側でage同士の引き算をしなければいけないところ、それをclass内に含めてしまうことができる、ということですね。 処理をclass内に含めてしまうことができる一方で、中でどのような処理が行われるのかを熟知している前提で実装する必要がある、ということでしょうか。 自分で実装することで、より理解が進んできた気がします。 このようなclassを使った実装の例題などがあるサイトやおすすめの本などございましたらご紹介いただけませんでしょうか? (何ができるようになるのか、がわからない為、答えを与えられてそれを実装する、というプロセスを回していきたく。)
iwamoto_takaaki

2016/10/20 07:44

> 関数だけで実装する場合は、外側でage同士の引き算をしなければいけないところ、それをclass内に含めてしまうことができる、ということですね。 そうです。もっと複雑なclassの場合はさらに効果的です。 > 処理をclass内に含めてしまうことができる一方で、中でどのような処理が行われるのかを熟知している前提で実装する必要がある、ということでしょうか。 むしろ、実装は気にせず入力と、出力の仕様を知っておくことが大事です。三角関数ライブラリの実装は知らなくてもつかうようなものです。 また、そのような実装を心掛けなくてはいけません。実装がわからなければ使えないならば設計を間違っているという考え方をしなければなりません。 実装を知らない前提にできれば、影響範囲が限定できます。ほかの部分がちゃんと動く前提にすれば、大きなプログラムも小さなプログラムも関係なく作ることができます。この点がclassを使う(オブジェクト指向)の最大の利点だと思っています。 > このようなclassを使った実装の例題などがあるサイトやおすすめの本などございましたらご紹介いただけませんでしょうか? 言語ごとに実例を集めたほうがいいです。ひとつづつの機能が理解できてもどころがわからないという意見は多いです。 そこでデザインパターンと呼ばれるテクニック集が開発されました。特にGoFのデザインパターンが有名です。C++やJavaでは有効なパターンです。しかし、ある言語のデザインパターンはある言語では標準機能で実装されているので覚える必要がなかったりがありますので(まったくの無駄にはなりませんが)ご注意ください。 Javaであれば私は結城浩さんの本がおすすめです。
uchi

2016/10/20 12:59

iwamoto_takaakiさん、ありがとうございます。 デザインパターンについては、LLmanさんのご回答にもありましたね。 もう少しレベルが上がってから調べてみます。 詳しいお話をありがとうございました。
guest

0

LLmanさんが回答されているように、小規模開発だと
なかなかメリットは実感できないように思います。

classというと「継承」が云々という話になりがちですが、
個人的には「カプセル化」というか隠ぺいといわれる
部分の方がより重要かなって思ってます。

話からははずれるかもしれませんが、
別のクラスだったら(変数や関数に)同じ名前をつけても困らない
ってのはいいなって思います。

あと、言語によって「クラス」がどう使えるかってのが
違ってくる場合があるので、その辺は要注意かも。
また、こういうのは自分で困って自分で解決できないと
なかなか実感できないように思いますので、
数をこなすしかないのかなあ、って面はあると思います。

投稿2016/10/19 07:49

takasima20

総合スコア7458

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uchi

2016/10/19 10:33

takashima20さん、ありがとうございます。 「カプセル化」とは利用者に、内部の構造を見せないようにすることでしょうか。 >数をこなすしかないのかなあ、って面はあると思います。 おっしゃる通りですね。数をこなして慣れてみます・・・。
takasima20

2016/10/19 11:10

カプセル化して内部を見せないことにより再利用が云々 という説明が多いように思いますが、外と中の関係を 薄めることによってプログラミングしやすくなる って(自分は)思ってます。
uchi

2016/10/20 06:10

takashima20さん、ご回答いただきましてありがとうございます。 >外と中の関係を薄める 中は中、外は外で区別することで、中の処理をまったく気にせずに機能を使えるようにする、ということでしょうか。何か少しだけ理解が前進した気がします。
takasima20

2016/10/20 10:18

そういう話っス。 難しくいうと「抽象化」ってやつですね。 ただし、このへんはclassに限った話ではないので、 いろんなとこで意識するといい感じになるです。
guest

0

クラスを使った例では、
nameとageという2つの状態をセットにして、一つのインスタンス(一つの状態)を作成しています。

それに対し、クラスを使わない例では、処理に対し2つの状態をバラバラに渡しています。

先ず、セットにしてラベルを付けると後から「参照」する場合に分かりやすいというのがあります。
「参照」とは実際にコード見る時だけでなく、頭の中で考えることや、人に説明する場合等、
ありとあらゆる、そのセットが必要となる場面(再利用の場面)という意味です。

クラスを使わない例でも配列や、構造体を利用することによりセットにすることができます。
しかし、配列では型制限がありますので、構造体ということになります。
構造体を利用することで複数が一つになり、分かり易くなります。

しかし、分かり易くする一方で、状態を内部に隠してしまいます。
また、プログラムの中では隠された状態が変化する為、根本的に分かり難いものと言えます。

クラスを使った例では
1、状態を作り
2、出力する。
の2手順です。
1を行った時点でどのような状態になっているかは
実際のインスタンスの内部を見るまで分かりません。
(クラスの実装によっては1がエラーにならなかったとしても、2が正解になる保証はありません。)
今回は連続していますが、間に多くの処理があったり、異なるファイルであったりした場合等
状態が悪い方向に働く側面もあります。
上記のような内部に隠ぺいされてしまう状態を副作用といったりします。

副作用に対して、オブジェクト指向ではカプセル化というテクニックを使って、
意図しない状態変更をさせないようにして、扱いやすくしています。
(ご存知だと思いますがアクセサがそれです。)
構造体にはカプセル化という機能が無く、すべて公開されてしまいます。

まとめると

バラバラな状態を一つに纏めて分かり易く。(マルチプルインスタンス
分かりずらい状態変更は制限をして扱う。(カプセル化

というのが、OOP時にどのような言語を利用しても
共通して見いだせるメリットとなります。

他にも表面的なメリットは沢山ありますが、
OOPと一重にいっても、言語により特徴があり、
言語のメリットなのかOOPのメリットなのか
区分けが難しい場合が多いです。
本質的な違いとは、上記のようなものというのが自分の認識です。

一人でプログラミング、且つ短い例題であると
メリットを見出すのは難しいですね。
大規模ならではというのはそれだけ多くの人が携わり、
再利用の場面が増えるからです。

投稿2016/10/19 07:45

wrmt

総合スコア28

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uchi

2016/10/19 10:30

wrmtさん、ありがとうございます。 メリットデメリットがあるのですね。一人でプログラミングする分にはメリットはないのかもしれませんが、世の中のサンプルプログラムやライブラリを活用する上では、理解しておかないと前進できないので壁に直面しているところです。
guest

0

PHP, VBA はオブジェクト指向ですよ。

VBAは "クラスモジュール" っていうやつでやります。

オブジェクト指向によるプログラミングとは( Yahoo! 知恵袋 )

上記ページの "bassiton" の回答。

俺流オブジェクト指向の入門

投稿2016/10/19 07:26

BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uchi

2016/10/19 10:14

BestSterさん、ありがとうございます。 >PHP, VBA はオブジェクト指向ですよ。 なるほど。その恩恵を受けるまでに深いプログラミングを書いていませんでした(汗 リンクをご紹介いただきありがとうございます。参考にいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問