読者です 読者をやめる 読者になる 読者になる

初心者向けにできるだけ噛み砕いてみるオブジェクト指向 vol.2 言葉を整理してみる

はじめに

dev.techdrive.top

上記の続きです。規格化することで様々な恩恵があるということをたとえで書いてみたのですが、読んでくださった方から

「USBケーブルの話が実際のプログラミングでの言葉ともっと繋がっているとよりわかりやすそう」

との意見をいただいたので、当初予定していなかったこの回を挟んでみました。実際考えてみると、このようなブリッジになる回はあったほうが良さそうに感じます。

今回は言葉がたくさん出てきますが、今丸暗記する必要はありません。ただ、今後の説明の中にはこれらの言葉が出てきます(これらの言葉を出さずに説明していくと冗長になって、かえって分かりにくくなってしまうので、積極的に使っていきます)。もしも言葉に混乱してしまったら、ここへ戻ってきていただければイメージが掴みやすくなると思います。というわけで行ってみましょう。

オブジェクト指向の道具たち

クラス

オブジェクト指向という話が出てきた時に、クラスの話が出ないことはほぼないと思います。 クラスは独自に新しい型を作るための仕組みです*1。主に下記の二つが幹になっています。

プロパティ

あるオブジェクトが持っている変数です。 クラスによって複数の変数をまとめて扱える、と考えても大きな間違いではないと思います。構造体という言葉がわかる人には、この性質は構造体と同じ理解でも概ね問題ないでしょう*2。 USBケーブルの話だと、ケーブルの長さやケーブルの色などがプロパティになる可能性が高いです。 インスタンス(後述)が持つ変数なので「インスタンス変数」と呼ばれたりもします。

メソッド

あるオブジェクトが持っている関数です。 プロパティの説明に寄り添えば、クラスによって複数の関数をまとめて扱えるということになります。クラスが持っている機能と言っても良いかもしれません。 USBケーブルの話だと、ケーブルを挿して別のものと繋ぐことができるという「動作」がメソッドになると理解すると良いと思います。

インスタンス

クラスは設計図のようなものなので、実際に使う場合には製品をつくるような実体化が必要になります。 インスタンスは設計図を実体化したものです。当然設計図に書かれた内容の性質をインスタンスが持つことになります。インスタンスのことをオブジェクトという言葉で表現する場合もあります*3

f:id:ms2sato:20170227020045j:plain

参考のコード

参考に、rubyでクラスを使ったコードを書いてみました。

#######################################
# ケーブルのクラス(設計図)を作る
#######################################
class BasicUsbCable 
  def initialize(length)
    @length = length # @length というプロパティを用意しています
  end

  # 長さチェック用のメソッド。
  # 届かせたい距離を distance として与えると、そこに届くかを判断してくれます。
  def reachable?(distance)
    @length > distance # 届くかのチェックは @length が距離よりも長ければ届く
  end

  # 接続用のメソッド。
  # USBDeviceを実装している device を渡せばいい感じにつながります。
  def connect_to(device)
    # 何か動作がいろいろとあるはず
  end
end

#######################################
# 以下は実際にBasicUsbCableを使うところ
#######################################

# 長さ3のケーブルを一つ作る。cable1はインスタンスです。BasicUsbCableクラスで定義した機能を持ちます。
# [クラス名].new するとインスタンス化されます。
cable1 = BasicUsbCable.new(3) 

# cable1に対して長さチェックをするメソッドである reachable? を呼び出します
cable1.reachable?(5) # 5の長さは届かないので false
cable1.reachable?(2) # 2の長さは届くので true

device = GreatSpeaker.new # GreatSpeakerはUSBケーブルで繋げる別のクラス。deviceはインスタンスです。
cable1.connect_to(device) # connect_toで接続する。


# 同じBasicUsbCableから別のケーブルも作れます
cable2 = BasicUsbCable.new(10) # 長さ10のケーブルのインスタンスを cable1とは別に 一つ作る
cable2.connect_to(device) # deviceには二本のケーブルが挿さっている

インターフェース or ダックタイピング

言語(今はその表現で許してください)によってはインターフェースという概念が提供されています。 これは持っているべきメソッド群をまとめた規格を表したものです。前回の内容でもありましたが、インターフェースが一致すると交換可能になります。

インターフェースが言語仕様に無いものの場合「持っているメソッドが(たまたまでも)同じだったら、同じ規格」と決めてしまうことがあります。 「アヒルのようなものはみんなアヒルとみなす」ということからダックタイピングと呼ばれています。

よく言われている機能や概念

道具としては上記のクラスを中心に行っていきますが、クラスの持つ機能や、よりよく作るための 概念として以下のようなものが有名です。

継承

あるクラスをもとにして、別のクラスを作ることです。 すでに完成しているものに対して新しい機能を追加したり、 途中まで作られた半完成品クラスを用意して、中身を入れて完成クラスを作るような方法で使います。 f:id:ms2sato:20170227022238j:plain

ポリモーフィズム(多態)

元々の意味合いとしては「同じ名前で機能の違うメソッドを色々なクラスに定義できる」ということなのですが、これだけだと何が嬉しいのかピンと来ないですよね。少し使いこなせると 「同じインターフェースを実装することで、差し替え可能にできる」というようなメリットを感じることができます。

このことはUSB規格を実装してさえいれば、別のケーブルを持ってきても挿し替えて使えたことと似ています。 f:id:ms2sato:20170227022244j:plain

カプセル化

「中のことをよく知らなくても使える」ように作ることです。 USB規格は「挿せば繋がる」ということを決めているので、USBケーブルの材質や、ケーブルの詳細な仕組みまでわからなくても使えることと似ています。 f:id:ms2sato:20170227022250j:plain

おしまいに

ちょっと色々な言葉が出てきていますが、よく出会う言葉でもあるので一度整理しておくと学習がはかどると思います。ちなみに、これらの基礎を私は多分「憂鬱なプログラマのためのオブジェクト指向開発講座」などで学んだと思うのですが(20年も昔の話なのでもう忘れてしまいましたが)、今の人たちはどんな方法で学ぶのでしょう。良書だったり、良WEBサイトがあったら是非知りたいです。

*1:String型やInteger型を普段使ってプログラミングしているかもしれませんが、これと同じようなものを自分で作れるということですね。

*2:クラスを「構造体に加えてメソッドも保有できるようにしたもの」という理解をする場合もあります

*3:この文章でもプロパティやメソッドの説明で「オブジェクト」と書いてしまいました

TECH DRIVEについて

TECH DRIVEは「技術者の成長を加速させる」をキーワードに都内で活動をしているコミュニティです。
TwitterやFacebookにて技術ネタやイベント情報の発信を行っていますので、ご興味があれば、いいねやフォローをお願いいたします。