【PHP】オブジェクト指向を学ぶ[その4]

#クラス定数
・クラスの中に作る定数のこと
・必ずpublicとして扱われるので、`privateやprotectedなどの修飾子は設定できない`
・クラス内で接続する場合は `self::定数名`
・クラス外で接続する場合は`クラス名::定数名`
まずはコード

```index.php
class Human{
    
    // 定数
    const MORNING = 'おはよう';
    const NOON = 'こんにちは';
    const NIGHT = 'こんばんは';

    private $name;
    private $gretting;

    public function __construct($name, $gretting){
        $this->setName($name);
        $this->gretting = $gretting;
    }

    private function setName($str){
        $this->name = $str;
    }

    public function introduction(){
        return $this->name.$this->gretting;
    }
    
}
$user1 = new Human('太郎', Human::MORNING);
$user2 = new Human('花子', Human::NOON);

echo $user1->introduction(); //太郎おはよう
echo $user2->introduction(); //花子こんにちは
```
見ての通りです。
インスタンスの第二引数にクラス定数を設定しています。

次は別にGreetクラスを作ります。

```index.php
class Human{
    
    private $name;
    private $gretting;

    public function __construct($name, $gretting){
        $this->setName($name);
        $this->gretting = $gretting;
    }

    private function setName($str){
        $this->name = $str;
    }

    public function introduction(){
        return $this->name.$this->gretting;
    }
}

class Greet{
    // 定数
    const MORNING = 'おはよう';
    const NOON = 'こんにちは';
    const NIGHT = 'こんばんは';
}

$user1 = new Human('太郎', Greet::MORNING);
$user2 = new Human('花子', Greet::NOON);

echo $user1->introduction(); //太郎おはよう
echo $user2->introduction(); //花子こんにちは
```
別にGreetクラスを作りました。
これもアクセス方法は一緒です。

クラス定数は、クラスが違えば同じ定数名でも動きます。

```index.php
class Human{
    
    private $name;
    private $gretting;

    public function __construct($name, $gretting){
        $this->setName($name);
        $this->gretting = $gretting;
    }

    private function setName($str){
        $this->name = $str;
    }

    public function introduction(){
        return $this->name.$this->gretting;
    }
}

class Greet{
    // 定数
    const MORNING = 'おはよう';
    const NOON = 'こんにちは';
    const NIGHT = 'こんばんは';
}

class Time{
     // 定数
     const MORNING = '朝です';
     const NOON = '昼です';
     const NIGHT = '夜です';    
}

$user1 = new Human('太郎', Time::MORNING);
$user2 = new Human('花子', Greet::NOON);

echo $user1->introduction(); //太郎朝です
echo $user2->introduction(); //花子こんにちは
```
このようにクラスが違えば同じ定数名でもそれぞれに対応した値を表示させることができます。
これをdefine()で行うとこうなります。

```index.php
define('Greet_MORING', 'おはよう');
define('Greet_NOON', 'こんにちは');
define('Greet_NIGHT', 'こんばんは');
define('Time_MORING', '朝です');
define('Time_NOON', '昼です');
define('Time_NIGHT', '夜です');

class Human{
    
    private $name;
    private $gretting;

    public function __construct($name){
        $this->setName($name);
    }

    private function setName($str){
        $this->name = $str;
    }

    public function introduction(){
        return $this->name.Greet_MORING;
    }
}

$user1 = new Human('太郎');
$user2 = new Human('花子');

echo $user1->introduction(); //太郎おはよう
echo $user2->introduction(); //花子おはよう
```

かなり分かりにくいですし、挨拶の言葉を変えるときに全てのメソッドを作らなければなりません。
クラス定数にしてしまえばそんなめんどくさいこともする必要はなくなりますね。

#抽象クラス
abstractとして定義されたクラスのインスタンスを生成することはできません。
コードはこちら。

```index.php
class Time{
    // 定数
    const MORNING = '朝です';
    const NOON = '昼です';
    const NIGHT = '夜です';    
}


abstract class Greet{
    protected $greet;

    public function setGreet($str){
        $this->greet = $str;
    }
    public function getGreet(){
        return $this->greet;
    }

    
    //抽象メソッドを定義したら継承先で必ずオーバーライドしなければならない
    abstract public function setSay($str);
    abstract public function getSay();

}

class Human extends Greet{
    protected $name;

    public function __construct($name, $greet, $say){
        $this->setName($name);
        $this->setGreet($greet);
        $this->setSay($say);
    }
    
    public function setName($str){
        $this->name = $str;
    }
    public function getName(){
        return $this->name;
    }


    public function setSay($str){
        $this->say = $str;
    }
    public function getSay(){
        return $this->say;
    }


    public function getIntroduction(){
        return $this->getName().$this->getGreet().$this->getSay();
    }
}

$user = new Human('太郎', Time::MORNING, 'やーーーーー！');

echo $user->getIntroduction(); //太郎朝ですやーーーーー！
```
これが抽象クラスです。
・classやメソッド前に`abstractct`をつける
・抽象メソッドは `継承先で必ず定義しなければいけない`（設定し使わなければいけない）

**※どこか間違っているところやこんなことも覚えておいた方がいいことがあれば是非教えてください。**