カプセル化
カプセル化 → getter、setterでprivate、protect、publicで直接属性にアクセスして値が間違って書き変わったりしないように、外部のコードからは参照できないようにして、getterで参照できるようにする。さらには年齢など年齢はコードの中で変わることはなく、何か入力したことで変わるものではないので、最初にインスタンスを生成するときにのみ年齢属性に値を入れて、それ以降は年齢属性へ完全に値を入れることができないよう、private化し、getterのみ実装する。
配列とオブジェクト
class Person{ $name; $age; $address; function __construct($name, $age, $address) { $this->name = $name; $this->age = $age; $this->address = $address; } } $person = new Person("name", 35, "tokyo"); print($person->age) // 年齢が欲しいならclassを見て年齢はどんなプロパティ名にしたかをみるだけで簡単にアクセスできる。さらに通常プロパティ名は英単語だったりするので、年齢=ageで慣れればすぐわかる
さらに資産を考えたとき、資産情報はこの中に記載するとなると
資産は名前、金額、カテゴリなど情報が必要になる。
じゃあ資産1は配列の要素10、11、12に情報入れるとする。そしてさらに資産が複数あったらその都度配列に値を入れていく。
そうなって資産の情報を用いて株価の計算などを行うとなった場合、配列から該当の金額は何番目に入っているかなどを常に追っていかないといけない。
到底そんなの何番目に値が入っているかなんて覚えていないので、配列から欲しい値がどこにあるかをprintしていちいち探さないといけなくなる。
$attr = ["name", 35, "tokyo"]; print($attr[1]); // 年齢が欲しい場合、要素の1番目にアクセスする
配列の中で様々な属性を入れていくことができますが、
上記の例では3つの要素ですが、ものすごい大きいプログラム/システムになった場合、上記のように3つではなく50個とかになったりします。
そうなった場合、50個の要素が入っていると何番目に自分の欲しい情報が入っているかわからなくなります。そして常にそれをみるためにprintしてデバッグします。
なのでかなり時間がかかってしまいます。
さらに配列で持つと、何かのプログラムのエラーなどで、$attr[2] = 1など想定しない値が入ってしまいバグが起きる可能性が出てきます。
どこで値が書き変わってしまったのか常にデバッグをする必要が出てきてしまいます。
そのため、クラス化してオブジェクトすることで、カプセル化し、そのような場合も防ぐことが可能になる。
上では、1つの配列に一気に値が入っている状況ですが、これがもし1000行のコードで
都度配列に値をpushしていき、
printしてとりたい値を取ることを想定した時、
どこで何番目に入ったかを追うことはかなり時間がかかり、開発の時間も取られてしまいます。
オブジェクト指向を考える
人(Person)というクラスを考えた時、
人の属性を考えていくと、人は
名前、年齢、出身、住所、性別、趣味、仕事、資産、、
など様々な属性があります。
その中でも、会社だったり、資産というものはさらにふかぼって属性などがあります。
例えば仕事は、所属会社、職種、役職など、資産であれば金融資産、未上場株式、生命保険金など資産の形も様々なものがあります。
さらに言えば金融資産などは資産の名前だったり、資産の金額などより深ぼることができます。
これらを考えた時、
人
・名前
・年齢
・出身
・住所
・性別
・趣味
・仕事
・資産
資産
・資産の種類(カテゴリ)
・資産名
・金額
という属性があると考えられます。
クラス化してみる
class Person{ private $name; //名前(通常名前は変わるものではないので、基本的にはprivateで頻繁に変更できないようにする) private $age; //年齢 private $gender; //性別 private $hobby; //趣味 private $address; //住所 private $asset; //資産(複数あれば配列の要素に複数のオブジェクトを入れる)[Asset(),Asset(),Asset()]というイメージ。参照の際は$person->asset[0]->name) public function __construct($name, $age, $gender, $hobby, $address, Asset $asset) { $this->name = $name; $this->age = $age; $this->gender = $gender; $this->hobby = $hobby; $this->address = $address; $this->asset = $asset; } } class Asset{ private $name; //名前(通常名前は変わるものではないので、基本的にはprivateで頻繁に変更できないようにする) private $age; //年齢 private $gender; //性別 private $hobby; //趣味 private $address; //住所 private $asset; //資産 public function __construct($name, $age, $gender, $hobby, $address, Shisan $asset) { $this->name = $name; $this->age = $age; $this->gender = $gender; $this->hobby = $hobby; $this->address = $address; $this->asset = $asset; } }
意外とわからないですが、
classのプロパティには他のクラスのインスタンスを入れることができます。
参考書などではclassには単発の値を入れるようなコードが多く、あまりプロパティに外部クラスのオブジェクトを入れるというイメージが湧きづらいですが、
そのようなことが可能になります。
このようにオブジェクト指向は様々な事象を「モノ(object)」としてみなし、