プログラミング

【プログラミング】オブジェクト指向についてまとめ〜クラス・コンストラクト・メソッド・アクセス権・継承・オーバーライド〜

オブジェクト指向とは?

オブジェクト指向とはプログラムの考え方のことです。オブジェクトとは「モノ」のことを指します。
例えば、「車」「人」などなど、色々な「物体」のことです。
オブジェクト指向に基づいてプログラムを書いていくことのメリットとして、コードの保守性が高くなります。
以下、オブジェクト指向について自分なりにまとめていきたいと思います。

参考:
PHPオブジェクト指向入門
クラスから理解するPHPのオブジェクト指向

クラス

プログラミングの設計図として「クラス」をまず作ります。

ここでは、RPG風にモンスターを題材にして進めていきたいと思います。

モンスターには以下のような共通点があります。共通点を最低限抜き出したのものがクラスの考え方になります。

共通のクラス名Monster
ロボットの特徴名前・HP
ロボットの機能攻撃

この共通点をプログラムに書いてみると以下のようになります。

  class Monster{ //クラス名
    // ロボットの特徴(プロパティという)
    public $name; //定義しただけだとnullが入ります。
    public $hp;

    // ロボットの機能(メソッドという)
    public function attack(){}//メソッドはクラスに所属する関数なのでfunctionがつきます。
  }

コンストラクト

先ほどクラスを作ることができましたね。次に、「コンストラクト」を定義したいと思います。

コンストラクトとは、インスタンスが生成された時に自動的に呼ばれる関数です。コンストラクトを呼び出して値を入れてあげます。

  class Monster{ 
    // プロパティ
    public $name; 
    public $hp;
    // コンストラクト
    public function __construct($name,$hp){
      // プロパティに値を入れる
      $this->name = $name;
      $this->$hp = $hp;
    }

    public function attack(){}//メソッド
  }

メソッド

コンストラクトの定義までできたので最後はメソッドです。メソッドは動きの部分を担うので、攻撃をしたら勇者のHPが減るという動きを書いてあげます。

  class Monster{ 
    // プロパティ
    public $name; 
    public $hp;
    public $attack = '';
    // コンストラクト
    public function __construct($name,$hp,$attack){
      $this->name = $name;
      $this->hp = $hp;
      $this->attack = $attack;
    }

    public function attack(){//メソッド
      $_SESSION['myhp'] -= $this->attack;
    }
  }

インスタンスの作成

クラスができたのでいよいよインスタンスを生成します。インスタンスとはクラスをコピーして作ったもののことです。
インスタンスを生成するときは、new クラス名(コンストラクトで使用する値の引数)と書きます。

$monster[] = new Monster('スライム',100,10);//$name,$hp,$attack

アクセス権

先ほどまでpublicなどをつけてきましたが、プロパティやメソッドには必ずつけなければいけないアクセス権(アクセス修装子)というものがあります。
アクセス修装子は全部で3つあります。

1.private→そのクラスからしかアクセスできない
2.protected→そのクラスと、サブクラスからしかアクセスできない
3.public→どこからでもアクセスできる

今まではどこからでもアクセスできるアクセス権を使っていたのですね。

ただ、これだとどこからでもプロパティを操作・書き換えができてしまいます。このどこからでも操作できてしまう(外部からアクセス)のを禁止し、プロパティを操作できないようにするのをカプセル化と言います。

  class Monster{ 
    // プロパティをpublicからprivateに書き換え(カプセル化)
    private $name;
    private $hp;
    private $attack = '';
    // コンストラクト
    public function __construct($name,$hp,$attack){
      $this->name = $name;
      $this->hp = $hp;
      $this->attack = $attack;
    }

    public function attack(){//メソッド
      $_SESSION['myhp'] -= $this->attack;
    }
  }

privateに書き換えてカプセル化ができました。これだけだと、読み取り・書き込みが何もできない状態なので、読み取りと書き込みができるようにしましょう。

書き込みにはセッターメゾット
読み取りにはゲッターメゾット

を使用します。

セッターメゾットは習わしとしてset〇〇ゲッターメゾットにはget〇〇という名前をつけましょう。

  class Monster{ 
    // プロパティをプライベートに書き換え
    private $name; 
    private $hp;
    private $attack = '';

    // コンストラクト
    public function __construct($name,$hp,$attack){
      $this->name = $name;
      $this->hp = $hp;
      $this->attack = $attack;
    }

    public function attack(){//メソッド
      $_SESSION['myhp'] -= $this->attack;
    }

    public function setHp($num){
      // セッターを使うことで、直接代入させずにバリデーションチェックを行ってから代入させることができる
      $this->hp = filter_var($num, FILTER_VALIDATE_INT);
    }

    public function setAttack($num){
      $this->attack = (int)filter_var($num,FILTER_VALIDATE_FLOAT);
    }

    public function getName(){
      return $this->name;
    }

    public function getHp(){
      return $this->hp;
    }

    public function getImg(){
      return $this->img;
    }
    
    public function getAttack(){
      return $this->attack;
    }
  }

継承について

クラスには「継承」という仕組みがあります。
継承とは、既に存在するクラスを元に、さらに拡張したクラスを作る仕組みです。
似たようなクラスだけど、少し違うというクラスを作る時に使用します。

//継承の使い方
  class クラス名 extends 親のクラス名{
  } 

この場合でいうと、魔法攻撃が使えるモンスターをMonsterクラスを継承して作ることができます。

  class MagicMonster extends Monster{
    private $magicAttack;
    function __construct($name, $hp, $attack, $magicAttack){
      // 親クラスのコンストラクタで処理する内容を継承したい場合には親コンストラクタを呼び出す。
      parent::__construct($name, $hp, $attack);
      $this->magicAttack() = $magicAttack;
    }
    public function getMagicAttack(){
      return $this->magicAttack;
    }
  } 

注意点として、privateがついているメソッド・プロパティは継承できません。
もし継承するなら親のクラスについているメソッド・プロパティのアクセス権をprotectedにしましょう。

オーバーライド

「オーバーライド」とは、継承することによって親クラスのメソッドを上書きする仕組みのことを言います。
親クラスのメソッドに追加機能を持たせたい・親クラスのメソッド機能を相殺したい時などに使用します。
オーバーライドの書き方は簡単です。

  class MagicMonster extends Monster{
    private $magicAttack;
    function __construct($name, $hp, $attack, $magicAttack){
      parent::__construct($name, $hp, $attack);
      $this->magicAttack() = $magicAttack;
    }
    public function getMagicAttack(){
      return $this->magicAttack;
    }
    // オーバーライド
    // attackメソッドをオーバーライドすることで、「ゲーム進行を管理する処理側」は単にattackメソッドを呼べばいいだけになる
    // 魔法を使えるモンスターは、自分で魔法を出すか普通に攻撃するかを判断する
  public function attack(){
      $attackPoint = $this->attack;
      if(!mt_rand(0,4)){//5分の1の確率で魔法攻撃
        $_SESSION['myhp'] -= $this->magicAttack;
      }
    }
  } 

少し長くなってしまったので、オブジェクト指向についての記事を分割します。