ULOG
記事
3人コメント2200p
読んだ
後で読む
クリップ
☆いいね!する
メニュー選択ブックマーク
スタンプフリー入力
コメント(無効)
ビッグエディタ
メダル(無効)
メニュー
ランキング
ユーザ登録
ヘルプ
ブログ内検索:
メダル(100)メダル(10)メダル(10)メダル(10)メダル(10)メダル(10)メダル(10)メダル(10)メダル(10)メダル(10)メダル(10)



この記事は後半は有料になっていますが、無料部分だけでも独立したコンテンツとして十分に役に立つような構成にしているので、有料部分を無視すれば通常のブログ記事と同じです。むしろ、無料部分だけでも通常のブログ記事の数十倍の手間をかけて書いてあります。
昔、私がオブジェクト指向プログラミングを学び始めたとき、あることを理解したら、まるで壁を突き抜けたように、学習がものすごく進んだことがありました。


http://www.my-freedom.org/fromdusktildawn/img/oo/breakthrough.png



逆に言うと、「壁」にひっかかっていることに気づかず、壁の手前でかなり無駄な時間を過ごしてしまったわけです。
中上級者にとっては当たり前すぎて今更な知識ですが、私の周りを見ていると、この壁のところにひっかかって無駄な時間をすごしてしまっている初学者の方がけっこういらっしゃるようですので、その壁を突破する鍵となった知識を、図解してみることにしました。



以下の図は、家の絵を描画するプログラムの動作イメージです。


http://www.my-freedom.org/fromdusktildawn/img/oo/array_picture.png



各オブジェクトのところにある「描く」メソッドは、『そのオブジェクトに対して「描く」メソッドを呼び出すことができる』という意味です。メソッドの定義自体は、下図のように、その所属クラスで定義されています。


http://www.my-freedom.org/fromdusktildawn/img/oo/array_picture_class.png



オブジェクトとクラスを一つの図に詰め込むと、以下のようになります。



http://www.my-freedom.org/fromdusktildawn/img/oo/array_picture_all.png



以下は、このプログラムの動作を示す擬似コードです。



http://www.my-freedom.org/fromdusktildawn/img/oo/arraypicture_pseudocode.png



「配列1」には「三角1」、「長方形1」、「長方形2」、「線1」の4つのオブジェクトが格納されており、ループを回して、それぞれのオブジェクトの「描く()」メソッドが順に呼び出されていきます。
「三角1」の「描く()」メソッドを呼び出すと、三角オブジェクトの「描く()」メソッドが実行されます。これは三角形を描画するメソッドです。
また、「長方形1」の「描く()」メソッドを呼び出すと、長方形オブジェクトの「描く()」メソッドが実行されます。これは長方形を描画するメソッドです。
この二つのメソッドは別のプログラムコードですが、どちらも「描く()」というメソッド名で呼び出すことが出来るようになっているのです。
このように、「異なる実装のメソッドを同じメソッド名で呼び出すこと」を、ポリモルフィズムと言います。

しかし、ポリモルフィズムの何が嬉しいんでしょうか?


それを見るために、パワーポイントにおける「図形のグループ化」を使ったプログラム構造を考えてみます。パワーポイントの「グループ化」とは、複数の図形をまとめて一つの図形として扱う機能で、ここではグループ化された図形を「複合図形」というクラスで実装してみます。オブジェクト構造と動作イメージは以下のようになります。


http://www.my-freedom.org/fromdusktildawn/img/oo/composite_picture.png


クラスとインスタンスの関係は以下のようになります。


http://www.my-freedom.org/fromdusktildawn/img/oo/composite_picture_class.png


クラスとオブジェクトの情報を一つの図に詰め込むと以下のようになります。


http://www.my-freedom.org/fromdusktildawn/img/oo/composite_picture_all.png


以下はその擬似コードです。


http://www.my-freedom.org/fromdusktildawn/img/oo/compositepicture_pseudocode.png


複合図形オブジェクトは、自分の子オブジェクトを格納した配列を持っています。
複合図形オブジェクトの「描く()」メソッドは、その配列をループで回して、全ての子オブジェクトの「描く()」メソッドを実行する、という実装になっています。
複合図形オブジェクトの子オブジェクトに別の複合図形オブジェクトが含まれている場合、ツリー構造の末端まで、再帰的に「描く()」メソッドが実行されていきます。
このようなクラス設計構造を「COMPOSITEパターン」と呼びます。オブジェクト指向設計におけるデザインパターンの1つです。


クラス定義から含めて、全部をRubyで書くと以下のようになります。


http://www.my-freedom.org/fromdusktildawn/img/oo/composite_picture_ruby.png


先頭の二行である「# encoding: Windows-31J」と「Encoding.default_external = 'Windows-31J'」は、日本語文字コードの指定です。文字化けしないようにするためのものです。(ここではWindowsで実行することを想定している)

クラス名の先頭に「C」がついているのは、Rubyのクラス名は大文字の英文字で始まらなければいけない、というルールがあるからです。

これを実行すると、次のような出力画面になります。

PS C:\oo> ruby .\composite_picture01.rb
(1,4)(7,4)(4,7)の3点を頂点とする三角形を描きました。
(2,1)(6,1)(6,4)(2,4)の4点を頂点とする長方形を描きました。
(3,2)(5,2)(5,3)(3,3)の4点を頂点とする長方形を描きました。
(4,2)から(4,3)への線分を描きました。
PS C:\oo>

次に、同じプログラムをJavaで書いてみます。

まず、Javaだとクラス名がそのままクラスファイルになるため、クラス名に日本語を使うと面倒なことが発生することがあるので、ここでは識別子は全部英文字にしてみました。

また、Javaの場合、下図のように「Picture」インタフェースを定義し、全ての図形クラスはPictureインタフェースを実装すると宣言してから、クラス定義しなければなりません。


http://www.my-freedom.org/fromdusktildawn/img/oo/java_composite_picture_class.png


コードは以下のようになります。


http://www.my-freedom.org/fromdusktildawn/img/oo/composite_picture_java.png



rubyの場合、単に「描く」メソッドを持っているオブジェクトを配列に格納してループを回せばそれでポリモルフィックなメソッド呼び出しが出来ますが、Javaだと配列に格納された全てのオブジェクトが「draw()」メソッドを持っていることを、ソースコード内で「保証」するような書き方をしないと、コンパイルエラーになります。(「バグがないこと」を「保証」しているわけではない)
Javaだと、「draw()」メソッドを持っていることを「保証」するやり方は二通りあります。
一つがインタフェースを使うやり方です。この例がそれで、「interface」宣言を使って「draw()」メソッドを持つ「Picture」インタフェースを定義し、各クラスが「implements Picture」という宣言をすることで、そのインタフェースを「実装」していることを明示しています。
もう一つが「継承」を使うやり方で、親クラスで「draw()」メソッドを定義し、その親クラスを各図形クラスが「継承」し、それぞれの子クラスで「draw()」メソッドの実装を上書きすることで、同様のことができます。

このように、Java言語だと「インタフェース」もしくは「継承」を使わないとポリモルフィズムが実装できませんので、それらがポリモルフィズムと一体不可分であるかのように錯覚してしまう方がときどきいらっしゃいますが、「インタフェース」も「継承」も使わずにポリモルフィズムを使ったクラス設計の出来るrubyのような言語を見て分かるとおり、それらはポリモルフィズムの本質とは直接関係があるわけではありません。


「COMPOSITE」パターンのキモは、「部品」と「部品の容器」を同じものとして扱うことです。

たとえば、ファイルとフォルダをどちらも「削除()」というメソッドで削除できるとします。
すると、ユーザのファイル削除操作の擬似コードは、以下のように記述することが出来ます。


http://www.my-freedom.org/fromdusktildawn/img/oo/oo_file_del.png


ポリモルフィズムを使わずにこれを実装しようとすると、以下のように、いちいち変数ファイル1に格納されているのがファイルであるかフォルダであるか、そのオブジェクトの種別を判定して、それによって処理を条件分岐させるという実装になります。


http://www.my-freedom.org/fromdusktildawn/img/oo/proc_file_del.png


フォルダとファイルの例だとオブジェクトの種類は2つしかありませんので、さほど煩雑にはなりません。
また、プログラムの規模が小さい場合、少々オブジェクトの種類が増えたところで、たいして煩雑にはなりません。

しかしながら、オブジェクトの種類が多くなるにつれ、また、プログラムの規模が大きくなるにつれ、この手の煩雑さはどんどん増加していき、可読性や保守性が落ちていきますので、それに対処するためにポリモルフィズムを使ったプログラミングの必要性が高まっていくのです。

前半(無料)はここで終わりです。

後半を読むにはメダル(約100円分)の付与が必要です。

後半では、いよいよ『継承を効果的に使って処理を記述する技法』を図解します。

「継承の概念と仕組みを理解すること」と、「『継承を効果的に使って処理を記述する技法』を習得すること」は別の話です。単に継承の概念と仕組みを理解しただけではダメで、「『継承を効果的に使って処理を記述する技法』を習得しないと、オブジェクト指向プログラミング技術はろくに身につきません。

後半の具体的な内容としては、(1)継承を使って処理を記述するためのクラス設計やオブジェクト構造の動作メカニズムを図解し、「継承を使って処理を記述することの、なにが嬉しいのか?」を説明します。

その次に、(2)「継承を使ったクラス設計の限界」を示し、その問題点を解決するためのクラス設計技法を図解します。

さらにその次に、(3)継承を使った処理の記述も、その限界に突き当たったときの代替案も、どちらも使わない方がよい場合について考察し、その見極め方について解説します。

最後に(4)この記事で使用した全てのサンプルプログラムのソースコードのテキストデータは、後半部分の末尾に貼り付けてありますので、実際に自分で動かして試してみることが出来ます。

この記事にメダルを付与する手順はこちらです。

本文(の一部)は非表示です。表示するにはメダル(100)付与が必要です。
※この記事の本文(もしくは本文の一部)は表示されていません。本文は、100メダルポイント以上のメダルをこの記事に付与した方にだけ表示されます。
メダルの入手や付与の方法が分からない方は、ここをクリックしてください
この記事を読むのに必要なポイント数分のメダルを付与する
この記事にコメント付きでメダルを付与する(無効)
メダルを購入する
ポイントを購入する
ユーザ登録する
  • 読んだ
  • 後で読む
  • クリップ
  • メニュー選択ブックマーク

ランキング   ■通算ランキング   ■メダルって?メダル付与    ■コメント&トラックバック一覧   ■ 2人、コメント2人、スタンプ2人、メダル200ポイント

最近書いた記事一覧
ブログ内検索:
■fromdusktildawnが書いた記事
「好きを貫く」よりも、もっと気分よく生きる方法
14個の身も蓋もない仕事の法則
「パクる能力」があるごく少数だけがパクって成功する
必要なら嫌われることでもやれるかどうかで運命が分岐する
経営戦略よりも重要なこと
僕が女子小学生にカモられた話
コミュニケーション能力をウリにする人が醜悪な理由
子供の「どうして勉強しなきゃいけないの?」→ 勉強することの具体的で直接的で切実なメリットを説明
「努力すればスキルが向上して上に昇れる」というのは幻想
 将来の不安を取り除き、人生の豊かさを最大化する戦略
 会社の意志決定機構をハックして年収を10~200%増やす技術(社内政治技術実践マニュアル)
「地道な努力」よりも、はるかに人生を好転させる努力の仕方
カップ麺なみの手間でできる6つの健康的激うま格安レシピ
ホリエモン以上に詐欺的なベンチャーの内情
睡眠の質を最高にする、ちょっと変わった夕食のとり方
無学歴、無職歴、無実力のニートが年収500万円の正社員になる方法
意外と知られてない、自分を飛躍的に成長させる読書テクニック
シリコンバレーをはるかに超える、世界一のイノベーション都市を、日本に作る方法
あまり知られてないけど、すごく効果のある花粉症対策まとめ
やがてくる大増税時代に豊かに生活するために準備すべきこと
できない理由を指摘する人よりできる方法を考える人が成功する理由
西暦2026年の日本
「おまえも空気の奴隷になれ」って?「空気読め」の扱い方次第で人生台無し
日本が公務員を大増員すべき4つの理由
ネットに時間を使いすぎると人生が破壊される。
自分を成長させ、人生を豊かにしてくれる有意義な会話をするコツ
ワーキングプアのNHK特集で取材された秋田県仙北町出身の友人と今日、昼飯を食いました
今の円高が錯覚である理由を中学生でも分かるように解説してみる
経営がわかっている労働者と、わかってない労働者の格差が拡大していく理由
会社側から待遇改善を勝ち取る交渉テクニック
女の子に好かれるための基本原則
日本でしか生きていけないと将来破滅するリスクがあるので、世界中どこでも生きていける戦略のご紹介
ネットの炎上は人類進化の必然で、健やかなる新時代を拓く鍵かもしれない
努力しない人を国家が救済すべき14の理由
優秀な人材に変身するキッカケに出会うか、未熟なまま老いていくか
「この人無能だな」と思われる人の3つの特徴
単なるプロフェッショナルを超える、「感動を生む仕事」をする人の13の特徴
あなたは自分の人生の経営者です。子供たちも既に自分の人生を経営しています。
シャンプーとリンスと石鹸は使わない方がいい
未来の転職が、過去にさかのぼって現在の自分を有能にする
思考の速度でパソコンを使う技術
現代という時代は、どのようなプログラミングを求めているのか?
Rubyの生産性の高さはどこまで本当か?
「IT投資」という考え方そのものが間違っている
「真実性を求めて分析・洞察した結果、みなが幸せになれる、政治的に正しい結論になりました」というパターンのブログ記事
「他人の生産性が向上すると自分の給料も増えるのか?」を中学生でもわかるように図解してみました
■fromdusktildawnのネットでの活動
・はてなブログ
・はてなブックマーク
・twitter
ブログ内検索:
【オイラの個人的お気に入り商品】

電気カフェケトル 0.8L
珈琲豆を挽いて湯を注ぐとき、湯量や勢いや注ぎ方の微妙な違いでクソ不味くなったりする。このケトルは湯の注ぎ口が細いので、繊細な湯量のコントロールが出来るので、いつでも美味しい珈琲を淹れたいオイラのような人間は重宝している。
【オイラの個人的お気に入り商品】

ドルツリニア 音波振動ハブラシ

最近の5000円以上のクラスの電動歯ブラシはマジで素晴らしい。昔使っていた安物の電動歯ブラシだとヘッドの動きがいまいちで良く磨けなかったり歯茎が痛かったりしたし、乾電池式だったのでので電池入れ替えるのが面倒だった。なので結局普通の歯ブラシに戻ってしまっていた。これは充電式なんだけど、クレイドルに置いておけば、非接触充電?か何かで勝手に充電される。便利だし、錆びないのでメンテナンスフリー。
【オイラの個人的お気に入り商品】

ドルツ ジェットウォッシャー

オイラは電動歯ブラシとフロスを使っているのだけど、それだけでは取れない汚れがあって、それを洗い流すのにこれを使ってる。
ジェットウォッシャーは強力な電動式水鉄砲みたいなもの。水圧で歯の汚れを取る。
電動歯ブラシとフロスで洗い流したにこのジェットウォッシャーをかけると、「汚れの味」がする。いつも、この「汚れの味」がなくなるまで、ジェットウォッシャーで歯を洗浄することにしている。そんなに時間はかからない。
あと、ジェットウォッシャーを使うと水でびちゃびちゃになるとか言う人がいるけど、単にやり方が下手なだけかと。オイラはぜんぜんそんなことはないですよ。