ここ最近のプログラム言語を習得する上で避けて通れない、クラスとは何かを解説します。
クラス、さらにオブジェクト指向まで解説すると、本が1冊書けてしまいます。
プログラム言語の本を読み進めてつまずくポイントは、クラスやオブジェクトともいえます。
しかしプログラミングで必要なレベルのクラスの知識を習得するのは、そう大変ではありません。
巷ではクラスはたい焼きの型、オブジェクトはたい焼きといったたぐいの「行き過ぎた比喩」が横行しています。
そもそもプログラミングとはまったく関係のないたとえ話で解説すること自体に無理があります。たとえ話を理解したところで本筋の理解にはつながりません。
そのような解説を読んで理解しようとして、プログラムと結びつけて考えることができず、何がなんだか分からないうちに挫折したという方も多いのではないでしょうか?
本記事ではRubyを使う上で最低限の知識にとどめて解説をします。
最初はコードを使いません。Ruby特有の知識も避けて解説します。
挫折した方も、ぜひ再チャレンジしてください!
ちなみに書籍の解説では、たい焼きやたこ焼きのいずれかを使った解説が多いです。筆者の好みや出身(関東?関西?)が関係しているのでしょうか・・・
さらに余談ですが、オブジェクト指向を理解できた方が、理解していない方から「クラスってなんですか?」という質問を受けると「そうだな、いってみればたい焼きの型とたい焼きだな。つまり・・・」と答えるようになるのは不思議です。
クラスとは何か?
クラスとは、メソッドや変数を寄せ集めたもので、そこからオブジェクトを生成し・・・という話は置いておきましょう。
ざっくりいうと、今の段階ではパーツの寄せ集めという理解で結構です。
分かりにくい解説に共通しているのは、クラス(というよりオブジェクト指向は、といった方が良いかも知れませんが)には、以下の2つの側面があることを説明していないからです。
- 開発の側面
- 設計の側面
順に解説していきます。
開発の側面
(文中ではメソッドという用語を使いますが、難しければ今のところは「関数」と置き換えてください)
プログラミングにおいて変数やメソッドを宣言し、さらにそれらを複数のメソッドで共有するというのは普通にありますよね。
変数とメソッドがひとまとまりになっていれば、重複して宣言することがないので便利です。
そのまとまりがクラスです。
ある特定の操作に関わる変数やメソッドを1つのクラスにまとめる、ということがよく行われます。
今まで出てきたクラスとして「Stringクラス」があります。Stringクラスには文字数をカウントしたり、大文字にしたり・・・という操作(メソッド)がまとめられています。
それらを私たちは簡単に使える、ということです。
例えば、文字列変数strの長さを調べるときには、「str.length」として簡単に呼び出せましたよね。
もう1つ、フレームワークを使うときもクラスを強く意識します。
Webシステム開発において、Ruby on RailsやLaravel、Springといったフレームワークを使うのが普通です。
フレームワークが基本部分(例えばデータベースへのアクセスやHTMLのレンダリングなど)をクラスとして提供していて、プログラマは各システムの固有の部分のみをコーディングする、といったことがよくあります。
よく聞かれるのは、共通関数で良いのでは?という意見です。
しかし共通関数とクラスとはまったく異なります。処理をまとめるというくらいしか同じ点はありません。
共通関数とのちがいは、後ほど解説します。
設計の側面
次に設計の側面です。
図書館の書籍管理を例にして考えましょう。
1冊の本には、だいたい以下のような属性(プロパティ)が存在します。
- No.
- タイトル
- 著者
- 出版社
- 出版年月日
- ページ数
書籍管理でいうとあとは冊数や貸し出し中の数、といったところでしょうか。
では、これをプログラムで管理するとしましょう。
はい、1冊目。
- No.1
- タイトル:Ruby入門
- 著者:honda
- 出版社:株式会社ポテパン
- 出版年月日:2017年12月1日
- ページ数:200
次に2冊目。
- No.2
- タイトル:PHP入門
- 著者:ポテパンライター2
- 出版社:株式会社ポテパン
- 出版年月日:2017年12月10日
- ページ数:150
そして3冊目・・・と続きます。
これをすべて変数で宣言する、というのは非現実的です。図書館なら蔵書数が何万になるのが普通です。ということは、上記の属性×蔵書数の変数・・・気が遠くなりそうです。
それを回避するために、こんなことをしてはどうでしょうか?
- すべての本に共通する属性を「型」としてまとめる
- 使うたびに型を実体化する
では型から実体の本を作成してみましょう。
まずはNo.1の本のみ、図にしてみます。
この調子で、複数の本を扱ってみましょう。
これだと、あつかう本の数だけ実体化できるので便利ですよね。
必要な分だけ実体化して使えばよいわけで、変数地獄に陥ることもありません。
すでに図で出てきましたが、この「型」がまさしくクラスというわけです。
これも図で出てきましたが、実体化したモノを「インスタンス」といい、実体する行為を「インスタンス化」といいます。
インスタンス化できることが、クラスと共通関数の大きな違いですよね。
プログラム設計ではこの話とは逆、つまり実在するモノから共通点を抽出しクラスを定義します。これを「汎化」といいます。
もうちょっとクラスを拡張(メソッド)
どうせだったら、クラスに関数を追加しましょう。
Bookクラスに本ごとの貸出可能数を得る関数があれば便利ですよね。
クラスをインスタンス化すれば、本ごとの貸出可能数を得ることができます。
インスタンスに紐付いた関数を「メソッド」といいます。
先に述べた関数とメソッドはちがうという理由はここにあります。
関数は単独で存在するもので、メソッドはインスタンスに紐づくものです。
ゲッターセッターアクセサーにカプセル化
インスタンスの中にある変数に直接アクセスするのは、いろいろと問題があります。
例えば以下のような例です。
実際の貸出可能数以上に貸出を受け付けてしまい、貸出できません。
よって、変数にアクセスするためのメソッドを用意し、そのメソッド経由でアクセスするのが普通です。
さらにそのメソッドに、妥当でない数値が入って来ればエラーとして遮断する、という機能をそなえると安心です。
このように、変数にアクセスするためのメソッドをアクセサーといいます。
言語によっては、変数から値を得るメソッドをゲッター(getter)、変数に値をセットするメソッドをセッター(setter)と呼びます。
アクセサーを関所とし、外部からのアクセスを遮断し、値と手続き(メソッド)をひとまとめにすることをカプセル化といいます。
まとめ
クラスとオブジェクトについて、ほんの入口だけですが解説しました。
いきなりすべてを理解しようとせず、今のところはこれで十分です。
なんとなく、分かったような分からないような、という感じではないでしょうか?
今後、実際にプログラムで解説していきます。
プログラムをみると、より理解が進むはずです。
めげずに、次に進んでくださいね!