Hello, World!!

むずかしいことはかけません

クラスとかプロパティとかメソッドとかアクセス修飾子とか

日頃なんとなーく書いてて、理解してるようで全然してないこれらを先輩に教えてもらったので整理していこうと思います。

クラス・プロパティ・メソッドとは?

クラスとは設計図、または雛形
プロパティとはクラスが持つ変数
メソッドとはクラスが持つ関数

コードで言うと以下のような感じ

<?php
// クラスを定義
class Car { 
    // プロパティを定義
    public $speed_public = 0;
    private $speed_private = 0; 

    // メソッドを定義
    public function get_speed() { 
        ~ 処理 ~
    }
}
?>

https://laraweb.net/surrounding/466/ のサイトがよりわかりやすい

なぜ private/protected がいいのか

またプロパティで宣言されているメソッドは基本privateだそうです。
なぜprivateなのかというと、クラスでは値(プロパティ)を更新したり、変更したりするのを用意します。
(Laravelではミューテタがその役割を担っています)

これらをもしprivateにしないと外から変数の値を勝手に変えられてしまうからです。
例えば以下のようなCarクラスがある時

<?php
class Car
{
    // ガソリン量(初期状態で20に設定)
    private $gasoline = 20;

    public function getGasoline()
    {
        return $this->gasoline;
    }

    // 運転
    public function drive()
    {
        if ($this->gasoline >= 10) {
            echo "運転中"."\n";
            $this->gasoline -= 10;
        } else {
            echo "給油してください"."\n";
        }
    }

    // 給油
    public function refuel()
    {
        $this->gasoline += 100;
        echo "給油中"."\n";
    }
}

$car1 = new Car();

$car1->drive();
$car1->drive();
$car1->drive();
$car1->refuel();  // ガソリン量が増える

echo "ただいまのガゾリン量:".$car1->getGasoline()."\n"; // ガソリンの量表示

出力結果

運転中
運転中
給油してください
給油中
ただいまのガゾリン量:100

もしプロパティ $gasolineがpublicなら

$car2 = new Car();
$car2->gasoline += 100; 

のようにして、クラス外からプロパティgasolineの値を変えることができます。

そうすることで、例えば上記プログラムでプロパティgasolineに入る量が50までと設定した場合
エラーは出ませんが、本来変数gasolineには20しか入らないのに、いつの間にか50入っていることになります。
そのため仮に変数gasolineを使うメソッドが他にあり、その際に50を超えた値になってると不具合が出てしまいます。

その不具合の原因が
$car2->gasoline += 100; と見つけることは難しい。
なぜなら $car2->gasoline += 100; そのものは普通に通ってしまっているため。

なのでプロパティで宣言されているメソッドは基本privateにして外部から値を変更できないようにすると不具合を見つけやすいということになります。
また、代入の流れをメソッドに書いておくと不正な値が入ることを弾ける(if文とかで)のでよい。

アクセス修飾子(public, protected, private)の違いは?

アクセス修飾子は以下の3つがあり

  • public
  • protected
  • private

この3つは関数の呼び出し方が違います。

public

どこからでもアクセスできる

protected

そのクラスと、サブクラス(継承先のクラス)からしかアクセスできない
サブクラスの関数のアクセス修飾子をprotectedにしないと使えない(publicでもいい)

private

そのクラスからしかアクセスできない