###前提・実現したいこと
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を使うことで実現できること(関数ではできない)、など、教えていただけませんでしょうか。
###すでに調べたこと
ネット上の諸先輩方のブログなどから、考え方は勉強しています。
これまでのプログラミング経験では、メソッド(関数)しか使ってこなかったため、
クラスとインスタンスの関係から概念がつかめていない為、そのあたりから勉強しています。
・クラスは設計図、インスタンスは具体例、インスタンスからクラス内のメソッドを呼び出して使う
という概念は、言葉では理解できていますが、いざ実装するとなると腹落ちしていません。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
0
こんにちは。
前者と後者は同じ出力を得ることができますが、やっていることは同じではないです。
前者はnameとageを一塊にして管理しています。後者はそれをしていません。
その差は、例えばMyClassの配列を考えると明らかです。
ここにちょうど同じようなクラスの配列を作る例がありました。
これを後者の形式で実現する場合、構造体を使ってnameとageを一塊にまとめ、グローバル関数showにそれを渡すイメージになるでしょう。
さて、異なる構造体を受け取って処理する別のshowを実装しないといけないケースもありますね。
その際にはshow構造体名()
のような名前を付けることも多いと思います。
それはshow構造体名(構造体のインスタンス)
の形式で呼び出します。
これは本質的にp1.show()と同じものです。
このような非常によく使われる一連のパターンをオブジェクト指向プログラミングと呼びます。
オブジェクト指向プログラミングを積極的にサポートしている言語で記述すると、より読みやすく よりメンテナンスしやすいプログラムを書くことができます。
投稿2016/10/19 07:30
編集2016/10/19 07:35総合スコア23272
0
classを使って構文を書くと、どうも遠回りしているよう
OOPが真価を発揮するのは大規模なプログラムです。
たとえると、オブジェクト指向は「ウサギとカメ」のカメです。
すなわち、プログラムが大きくなってもバグによる減速が少ないので、
トータルで見れば早いという考え方です。つまり急がば回れ。
classを使うことによるメリット、理解の方法
「デザインパターン」を理解すると、OOPを使うメリットも分かります。
デザパタの多くが、OOPの継承や多態を利用したパターンだからです。
もっと具体的に言うと、構造化技法では制御文の入れ子が深くなりがちですが、
if文をストラテジーなどで置きかえると整理されるので、メリットが実感できます。
投稿2016/10/19 05:39
総合スコア5592
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
classを使うことによるメリット、理解の方法、classを使うことで実現できること(関数ではできない
Pythonにはモジュールという機能があるため、単純にモジュールに変数と関数を定義することも、クラスを作ることもできます。
どちらにもメリットがあるため、Pythonのエキスパートの人達はこれらを上手く使い分けています。
関数ではできない一番大きな機能は継承が使えない点です。
継承についてはここでは割愛しますが、非常に便利な機能です。
また、モジュールは一個のコピーしかロードされないという特性も心の隅に留めておきましょう。
(GoFのデザインパターンで言うとシングルトンとして使える)
これにより、クラスのように同じメソッドを持つが異なる属性(内部の変数等)のインスタンスを多数作成する...ということがモジュールでは難しいことも意味します。
逆に言うと、1つしか使わないオブジェクトであればモジュールに関数と変数を定義するだけ充分な場合も多いです。最たる例は、settings.pyのような設定ファイルですね。
辞書の値が長いタプルやリスト、別の辞書になるような複雑なデータ構造になった場合は、こちらもクラスを使った方が柔軟で、分かりやすいものになります。
まずは上の3つぐらいを意識し、とりあえず関数だけで書いていくスタイルでも良いかなぁと思います。
後は自分で作っていれば慣れていきますし、優秀なライブラリやフレームワークを使いながら、それを勉強するのも良いかと思います。
投稿2016/10/19 16:48
編集2016/10/19 17:01総合スコア972
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/20 06:54
2016/10/20 11:17
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
総合スコア2883
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/20 06:48
2016/10/20 07:44
2016/10/20 12:59
0
LLmanさんが回答されているように、小規模開発だと
なかなかメリットは実感できないように思います。
classというと「継承」が云々という話になりがちですが、
個人的には「カプセル化」というか隠ぺいといわれる
部分の方がより重要かなって思ってます。
話からははずれるかもしれませんが、
別のクラスだったら(変数や関数に)同じ名前をつけても困らない
ってのはいいなって思います。
あと、言語によって「クラス」がどう使えるかってのが
違ってくる場合があるので、その辺は要注意かも。
また、こういうのは自分で困って自分で解決できないと
なかなか実感できないように思いますので、
数をこなすしかないのかなあ、って面はあると思います。
投稿2016/10/19 07:49
総合スコア7458
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/19 10:33
2016/10/19 11:10
2016/10/20 06:10
2016/10/20 10:18
0
クラスを使った例では、
nameとageという2つの状態をセットにして、一つのインスタンス(一つの状態)を作成しています。
それに対し、クラスを使わない例では、処理に対し2つの状態をバラバラに渡しています。
先ず、セットにしてラベルを付けると後から「参照」する場合に分かりやすいというのがあります。
「参照」とは実際にコード見る時だけでなく、頭の中で考えることや、人に説明する場合等、
ありとあらゆる、そのセットが必要となる場面(再利用の場面)という意味です。
クラスを使わない例でも配列や、構造体を利用することによりセットにすることができます。
しかし、配列では型制限がありますので、構造体ということになります。
構造体を利用することで複数が一つになり、分かり易くなります。
しかし、分かり易くする一方で、状態を内部に隠してしまいます。
また、プログラムの中では隠された状態が変化する為、根本的に分かり難いものと言えます。
クラスを使った例では
1、状態を作り
2、出力する。
の2手順です。
1を行った時点でどのような状態になっているかは
実際のインスタンスの内部を見るまで分かりません。
(クラスの実装によっては1がエラーにならなかったとしても、2が正解になる保証はありません。)
今回は連続していますが、間に多くの処理があったり、異なるファイルであったりした場合等
状態が悪い方向に働く側面もあります。
上記のような内部に隠ぺいされてしまう状態を副作用といったりします。
副作用に対して、オブジェクト指向ではカプセル化というテクニックを使って、
意図しない状態変更をさせないようにして、扱いやすくしています。
(ご存知だと思いますがアクセサがそれです。)
構造体にはカプセル化という機能が無く、すべて公開されてしまいます。
まとめると
バラバラな状態を一つに纏めて分かり易く。(マルチプルインスタンス
分かりずらい状態変更は制限をして扱う。(カプセル化
というのが、OOP時にどのような言語を利用しても
共通して見いだせるメリットとなります。
他にも表面的なメリットは沢山ありますが、
OOPと一重にいっても、言語により特徴があり、
言語のメリットなのかOOPのメリットなのか
区分けが難しい場合が多いです。
本質的な違いとは、上記のようなものというのが自分の認識です。
一人でプログラミング、且つ短い例題であると
メリットを見出すのは難しいですね。
大規模ならではというのはそれだけ多くの人が携わり、
再利用の場面が増えるからです。
投稿2016/10/19 07:45
総合スコア28
0
PHP, VBA はオブジェクト指向ですよ。
VBAは "クラスモジュール" っていうやつでやります。
オブジェクト指向によるプログラミングとは( Yahoo! 知恵袋 )
上記ページの "bassiton" の回答。
投稿2016/10/19 07:26
総合スコア4958
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/19 10:16
2016/10/19 10:41
2016/10/20 06:09