今回は、オブジェクト指向プログラミングのはじめの一歩を、PHPのコードを使って説明しています。
この記事では、以下のような期待に応えます。
オブジェクト指向プログラミングを学べる書籍を知りたい
PHPによるオブジェクト指向プログラミングの簡単なサンプルコードを見たい
今回は、このようなオブジェクト指向プログラミングの基礎的な知識などについて知りたい方の為に、PHPのコードを使って解説します。
PHPでのオブジェクト指向プログラミングを学習する、とっかかりになる記事になっています。サンプルコードもありますので、ぜひ手を動かしながら学習のお役に立ててくださいね。
PHPでオブジェクト指向プログラミングについて学ぼう!
オブジェクト指向の概念とは?
オブジェクト指向ではよく「概念」という言葉が使われるので、なんとなく分かりづらいイメージがありますよね。とはいえ、エンジニアにとってオブジェクト指向の概念を理解することは必須なので、少しずつでもその考え方に慣れていきましょう。
まず、オブジェクト指向をシンプルに説明すると、「オブジェクト=モノ」の作成と「操作」に分けてプログラミングしていく考え方になります。例えば、この考え方をレーシングゲームの「車(モノ)」に置き換えた場合どうなるか解説しますね。
■オブジェクト指向を「レーシングゲーム」で例える
上記のように「モノ=車」と「操作=◯で加速、✕で減速」に分けてプログラミングする考え方が、オブジェクト指向ということになります。
オブジェクト指向の概念を理解することはプログラミングの効率化にも繋がり、エラーやバグが起きた時の原因も見つけやすくなります。またプログラムの方向性が変わった時、変更を加えるのが容易になることもメリットですね。
実践を繰り返しながら、オブジェクト指向プログラミングを積極的に活用していきましょう。ちなみにオブジェクト指向については、以下の記事でも詳しく解説していますので、ぜひ参考にしてみてください。
PHPとは
PHPは、Webアプリを制作するためのプログラミング言語です。PHPがリリースされた当初は、オブジェクト指向プログラミングには対応していなかったため、上で説明したような「カプセル化」は不可能でした。一方、PHPと同じようなスクリプト言語であるPython、Ruby、Perlなどがオブジェクト指向プログラミングに対応していました。
そのような時代の流れもあり、1998年にリリースされたPHP 3からオブジェクト指向プログラミングへの対応を始め、今ではPHPでのオブジェクト指向プログラミングは一般的になりました。
有名なフレームワークである「CakePHP」を使う際も、オブジェクト指向プログラミングの概要を理解している必要があります。
なお、PHP初心者に向けてPHPの特徴やできること、基礎学習については以下の記事で詳しく解説していますので、ぜひご覧ください!
オブジェクト指向を知る上で大切な要素とは
オブジェクト指向を理解するうえで必要になってくる大切な4つの要素を解説しますので、まずは一通り覚えておきましょう。
カプセル化
「カプセル」というと、おそらくほとんどの方がお薬のカプセルをイメージするのではないでしょうか?カプセルの中に詰め込まれた粉末状の薬は、カプセルによって保護されているので他のモノと混ざることを防ぎ、外気からも守ってくれますよね。
オブジェクト指向における「カプセル化」も基本的に考え方は似ています。ある一定範囲のプログラムをカプセルとして保護し、不適切なプログラムの変更や不正アクセスから守るという目的を担うのが「カプセル化」です。要するに必要性のないプログラムからの干渉を防いで、管理・効率化につながるメリットがあるということですね。
オブジェクト指向のプログラミングにおけるカプセル化を実行するには「クラス」というものを使いますが、詳しくはこの記事の後半でサンプルコードを載せて解説しているので、そちらを参考にしてください。
継承
「継承」は大規模なシステムやアプリケーションの開発において、記述されたプログラムが膨大な量となった時、「コードの再利用」などのために使われる要素です。
プログラムが大量になるほど似たようなコードが記述されてしまう傾向があり、想定外のバグやトラブルの原因となることがあります。メンテンナンスも容易ではなくなりますし、そういったトラブルを避けるべく、重複しているコードをまとめ、それらを再利用して作業の効率化とミスを防ぎ、さらに機能の拡張性を向上させる目的として「継承」という概念は存在しています。
抽象化
「抽象化」もオブジェクト指向に欠かせない要素ですが、その概念を言葉だけで分かりやすく伝えることはちょっと難しいです。初心者であれば抽象化を理解するまでは、ある程度時間がかかるかもしれません。
抽象化を一言で要約すると「指示を曖昧にせず明確にすること」を抽象化ともいえますし、「重要な部分を抜き出して、ほかは除外する」という解釈をする人もいます。
曖昧なコードが記述されていると結果的にバグを引き起こす要因となりますよね? そこの指示(コード)を明確で、なおかつ適切な記述にする、という考え方だとして覚えておきましょう。
「Wikipedia」でも抽象化について解説されていますので、参考までに読んでおいてもいいでしょう。
ポリモーフィズム
「ポリモーフィズム」とは、日本語では「多様性」「多態性」などと訳され、簡単に要約すると「そのモノらしい固有の振る舞い」を可能にする概念ということになりますね。「継承」の概念でコードの再利用性について解説しましたが、ポリモーフィズムも再利用性についての考え方は似ています。
継承と違う点は、同じ指示を出してもそれぞれに固有の異なる処理をさせる特性にあります。
イメージが湧かないと思うので、3匹の動物「すずめ」「カラス」「ひよこ」を例にして説明しますね。この3匹の鳥に「鳴け」とだけ指示をすると、すずめは「チュンチュン」、カラスは「カーカー」、ひよこは「ピヨピヨ」という鳴き声を発するはずですよね?これが一般的な認識であり「そのモノ固有の成り立ち」になるはずです。
このようにポリモーフィズムは、一つの指示だけで「そのモノらしい固有の振る舞い」を実行させる「多様性・多態性」を取り入れたプログラムの考え方になります。
オブジェクト指向はなぜ必要なのか?
ここまではオブジェクト指向の基本概念などを説明してきました。カプセル化や継承機能はとても便利な機能であることが理解できたでしょう。しかし、このような機能を含む「オブジェクト指向」とはなぜ必要なのでしょうか。
オブジェクト指向の必要性としては、主に以下のようなことがあります。
- 機能変更が簡単になる
- ソースコードの可読性が高くなる
まず、オブジェクト指向で記述されたプログラムは、コードの継承などをすることで使い回しのきく記述ができます。そのため、もしプロジェクトの途中で機能変更や修正があった際には、もともとのソースコードを変更するだけで済みます。
もう一つのメリットとしては、ソースコードの可読性が上がることがあります。オブジェクト指向でないソースコードというのは似たようなファンクションが存在するなどして無駄が多く、可読性が低くなります。しかし、PHPで基本的に採用されているオブジェクト指向で記述すれば、第三者が見てもわかりやすいのが特徴です。
このような理由から、PHPではオブジェクト指向でプログラミングしたほうが良く、ぜひ覚えてほしい項目です。
では、次の章でオブジェクト指向とそうでないプログラムを比較して、オブジェクトの必要性についてもう少し深堀りしていこうと思います。
オブジェクト指向とそうではないプログラムを比較
ここまででオブジェクト指向の概念や必要性などを説明してきました。そんなオブジェクト指向ですが、クラスを使うと利便性が上がるわけではありません。単純な処理を記述する際には、わざわざクラスを作って定義すると逆に複雑化してしまいます。
そのため、時と場合を考慮してオブジェクト指向を使いこなす必要があります。簡単な消費税の計算をするサンプルコードをお見せします。
オブジェクト指向を用いた記述例
class Tax { public $taxRate; public $price; public function calTax(){ return ($this->price * $this->taxRate); } } $tax = new Tax(); $tax->taxRate = 0.1; $tax->price = 100; echo $tax->calTax();
このように、クラスを定義しオブジェクト指向を用いて記述してみました。ではこれをオブジェクト指向ではない方法で記述してみます。
オブジェクト指向ではない記述例
function calTax($price, $taxRate){ return ($price * $taxRate); } $taxRate = 0.1; $price = 100; echo calTax();
このようになります。今回出したサンプルコードは処理がそこまで複雑ではないので、オブジェクト指向で記述した前者のコードの方がコード量が増えています。しかし、前者のオブジェクト指向で記述したコードにも良いところがあり、それが「引数の指定間違いが無くせる」ことです。
このように簡単な処理であれば、オブジェクト指向で記述する恩恵はそれほど受けることはできませんが、実戦向きの複雑な処理に慣ればなるほど、オブジェクト指向の真価を発揮します。
では、次からはそのようなPHPのオブジェクト指向を学習できるのに最適な本を紹介します。
PHPのオブジェクト指向を学習できる本
オブジェクト指向プログラミングを学べる、おすすめの本を3冊選んでみました。
オブジェクト指向のこころ (SOFTWARE PATTERNS SERIES)
プログラミングには、よく使われる設計パターンがあり、この設計パターンのことを「デザインパターン」と呼びます。オブジェクト指向プログラミングとデザインパターンは相性がよく、非常に効率的にプログラムを書けるようになりました。
この本では、デザインパターンの中から、重要度の高いものを厳選し、解説しています。サンプルコードは主にJavaですが、考え方は参考になりますよ!
オブジェクト指向でなぜつくるのか 第2版
こちらもサンプルコードはJavaですが、オブジェクト指向プログラミングの全体像を平易な文章で説明した良書です。
オブジェクト指向プログラミングの概念を説明するだけでなく、フレームワークやデザインパターンなども整理して解説することで、オブジェクト指向プログラミングの全体像を理解しやすくなっています。
オブジェクト指向入門 第2版
本の名前に「入門」と書かれていますが、なかなか難しい本で、ここから読み始めるのはおすすめできません。サンプルコードはEiffelです。一方、ひととおりオブジェクト指向の概要を理解してから読むと、オブジェクト指向プログラミングの本質をドンドン理解できるでしょう。
この本が理解できるようになったら、オブジェクト指向プログラミングをマスターしたと言っても良いでしょう。
レベル別PHPのおすすめの本
PHPでオブジェクト指向プログラミングを学習するには、やはりPHPの学習本を読んだ方が近道です。概念を大ざっぱに理解した状態でも、プログラムを書いていけば徐々に理解が深まります。
PHPの学習本を使って、オブジェクト指向プログラミングに挑戦していきましょう!PHPのおすすめの学習本については、以下の記事で解説しています!
PHPを効率よく学べる学習サイト
PHPによるオブジェクト指向プログラミングを効率よく学ぶには、無料の学習サイトを使用する方法もあります。ちょっとした空き時間を無駄にせず、自分のペースで学べますし、一度では理解できなかった概念があったとしても様々な学習サイトを利用することで、理解が深まることもあります。
初心者でも分かりやすく解説している学習サイトもあれば、ある程度理解している状態の読者に向けて、より深い内容を説明している学習サイトもあります。いくつもの学習サイトを読んだとしても、無料であれば安心ですよね。
以下の記事では、PHP初心者向け講座のスライドを紹介しています。スライドをざっと見ていくだけでも、PHPの基本の知識を押さえられますよ。
PHPの学習で役立つQ&Aサイト
プログラミングを独学で学習している初心者の方は、疑問点があったりエラーやバグで自分では対処できない状況になったら、以下で紹介するQ&Aサイトも活用してみましょう。
teratail(テラテイル)
「teratail(テラテイル)」はプログラミングに関するQ&Aサイトでは鉄板です。国内でも規模はトップクラスですし、回答率も90%を維持しています。初歩的な質問であっても丁寧に答えてくれる方が多いのも人気の理由でしょう。
まずはマナーとして自分で調べてみて、どうしても分からないという時は一度質問をしてみてください。きっとあなたの悩みは解決するはずです。
stack overflow(スタック・オーバーフロー)
「stack overflow(スタック・オーバーフロー)」もエンジニアが利用するサイトとしては有名です。回答率は80%近くなので、Q&Aサイトとしては十分に機能していますし、プログラミングに関する有益な情報がたくさん得られますよ。
GoogleやFacebookのアカウントですぐに登録できるところも便利かと思います。
ココナラ
「ココナラ」でも多少お金はかかりますが、「IT・プログラミング・開発の相談」というカテゴリがあるので、プロのエンジニアに技術的な相談をすることはできます。事前に相談相手のプロフィール、スキルレベル、販売実績・評価を確認できるので、チェックをしっかり行っておけばハズレを引く確率も減るでしょう。
ただ申し込みの枠が埋まっていたり、状況によっては返答まで時間がかかる場合もあるので、理解したうえで申し込んでください。
Qiita(キータ)
「Qiita(キータ)」はQ&Aサイトというよりは、エンジニアがその知識や経験を共有するサイトというコンセプトなのですが、質問ができないというわけではないです。自分の投稿ページに困っている状況を正確に記載しておけば、親切な人にコメント欄から回答を得られるケースはあるようです。
回答についてあまり過度な期待はできませんが、公開されている情報は有益なので学べることが多いはずです。
Yahoo!知恵袋
「Yahoo!知恵袋」も「プログラミング」のカテゴリから質問をすることは可能ですね。ただプログラミングに特化したQ&Aサイトではないので、回答者のリテラシーもバラつきがあり、あくまでも参考までにしておいた方が無難だと思います。
すでに解決済みの質問を閲覧して、回答欄から有益そうな情報だけをインプットしておくという利用のしかたもいいでしょう。
まずは自分で解決策を調べる
プログラミングを学習していれば、バグなどでつまずき、手が止まってしまうことは何回でも起きるはずです。そばにベテランのエンジニアがいればすぐに聞いていいかもしれませんが、まずは自分で解決策を調べることがWeb業界の基本でありマナーです。
これはプログラミングに限らずですが、問題解決能力が低い人は成長スピードも遅いです。解決策を調べている過程で色々な知識が自然とインプットされているので、その時間は決して無駄にはなりません。
ただ、10時間くらい自分で調べたけど解決できずに質問したという方もいますが、いくらマナーだからといってもこれはちょっとやり過ぎかなとも思います。ある程度ネットで調べて解決策を試した結果、改善しなければ先ほど紹介したQ&Aサイトなどを利用してみましょう。
質問するコツについては、以下の記事でも詳しく解説していますので、ぜひ参考にしてください。
相手の時間を奪い過ぎない
メールや口頭で特定の人にプログラミングについて相談する時は、その人の時間を自分の為に使ってもらっているという意識を忘れないようにしましょう。常識的なことですが、意識できていない人は意外と多くいらっしゃいます。この気づかいができない人は相手からの印象も悪くするので、結果的に「損」をします。
質問をする時は、問題点の冷静な把握、自分で調べて試した解決策、そして現在どのような状況であるのかをきちんと整理して伝えてあげるようにしましょう。できるかぎり相手の時間を奪わないという意識があれば、誰でも自然に気づかいのある質問ができます。
PHPのオブジェクト指向をサンプルコードで理解しよう
PHPのクラスや関数の使い方について
ここからは、少し具体的にPHPによるオブジェクト指向プログラミングを見ていきます。オブジェクト指向プログラミングのメリットである「カプセル化」を体感するため、値が1ずつ増えるカウンターを見てみましょう。
<?php class counter { // counterクラスの定義(ここから) // counterクラスの定義 var $count; public function __construct(int $c) { $this->count = $c; } public function get() { return $this->count; } public function increment() { $this->count++; } } // counterクラスの定義(ここまで) // counterクラスの利用 $counter = new counter(100); echo $counter->get() . "<br />"; $counter->increment(); echo $counter->get() . "<br />"; $counter->increment(); echo $counter->get() . "<br />"; $counter->increment(); echo $counter->get() . "<br />"; ?>
細かいところを省略すると、以下のようにcounterクラスを定義し、counterクラスを利用する構造になっています。
class counter { // counterクラスの定義(ここから) // counterクラスの定義 } // counterクラスの定義(ここまで) // counterクラスの利用
counterクラスの定義
counterクラスの定義から見ていきましょう。
counterクラスを利用する方法は、以下の3つだけを定義しました。
- public function __construct(int $c):値を初期化する
- public function get():値を取得する
- public function increment():値を1増やす
任意の値を設定できるのは初期化時だけにし、初期化後は自由な値を設定することも、値を減らすこともできない設計です。なお、この3つは関数と同じfunctionキーワードを使用していますが、関数とは呼ばずに「メソッド」と呼びます。
counterクラスの実体化
ここまでで説明したcounterクラスはあくまで定義であって、利用するには実体を用意する必要があります。PHPに用意されている整数型(integer)と比較しながら、counterクラスの実体を用意する方法を説明しましょう。
整数型の変数を利用するには、以下のように変数を用意して整数を代入する必要があります。
$money = 100;
これに、少しキーワードを書き加えることで、counterクラスの実体を用意できます。
$counter = new counter(100);
「new」が、クラスを実体化するためのキーワードです。
「counter()」は、counterクラスを指し示しています。
ちなみに、クラスを実体化したモノを「オブジェクト」と呼びますので、覚えておきましょう。ここで例示しているプログラムでは、定義のことをcounterクラスと呼び、実体のことをcounterオブジェクトと呼ぶと理解してください。
1つのクラスに対して複数のオブジェクトを作成できますが、今回は「カプセル化」に焦点を合わせたいので、説明を省略します。
counterオブジェクトの操作
前もって、「counterクラスを利用する方法を3つ定義した」と説明しましたが、これは、「実体であるcounterオブジェクトを操作する方法が3つある」という意味でもあります。
作成したcounterオブジェクトを操作するには、->(矢印演算子)を使って、counterクラスで定義したget()メソッドを呼び出します。
echo $counter->get() . "<br />";
このコードは、counterオブジェクトの値を取得して、Webページに表示しています。
1回目の呼び出しでは「100」が表示されます。
次に、同様の書きかたで、increment()メソッドを呼び出します。
$counter->increment();
これで、counterオブジェクトの値が1増えます。
1増えていますので、2回目のget()メソッドの呼び出しでは「101」が表示されます。あとはここまで説明したことの繰り返しになりますので、実際に動かしてみてくださいね。
以上で、counterクラスの定義と、counterオブジェクトの利用を通じて、カプセル化のイメージがつかめたでしょう。PHPのクラスの使いかたについては以下の記事で詳しく解説していますので、あわせてご覧ください!
まとめ:PHPもオブジェクト指向もまずは実践してみよう
オブジェクト指向プログラミングの実例として、非常に簡単なcounterクラスを紹介しました。実はこのcounterクラスには、オブジェクト指向プログラミングのキモの1つである「カプセル化」の考え方が含まれていました。
たとえば、counterクラスを利用するときに、counterクラスの値を「$count」という変数が保持していることを気にする必要がありません。またcounterクラスの値は、初期化時しか任意の値に設定できないこと、それから値を減らせないことも大切なことです。
このように、クラスの利用者がクラスの内部構造を詳細に理解していなくても、利用する上ではまったく問題がないことが「カプセル化」の特長です。
もちろん、オブジェクト指向プログラミングは「カプセル化」を理解しただけでは、まだまだ不十分です。理屈だけでは面白くないと思いますので、オブジェクト指向プログラミングを実践しながら、その他の特徴も理解していってください!