PHPのクラス、インスタンス、継承について

# クラスとは
```クラス```とは***変数、定数、関数をひとまとめ***にしたものです。

ex)
変数/定数->プロパティ
関数->メソッド


# オブジェクト指向
```オブジェクト指向```とは***役割を分けていくイメージ***です。
例えば漫画のワンピースで例えると、
航海士、医者、船大工、コックなどそれぞれ役割がありますよね。
航海士クラス、医者クラスのようにクラスを分けていくことです。


Rubyの資料ですが、参考にしてみてください。

https://qiita.com/Hashimoto-Noriaki/items/a9cec16753db70c52033

# オブジェクト指向の3大要素
3大要素は下の3つです。

1.```カプセル化```
メソッドなどを定義した役割を分けることです。

2.```継承```
クラスや関数を引き継ぐ役割があります。

3.```ポリモーフィズム```
同じ役割のものでも新しい役割ができていくイメージです。


# 便利なブログ
わかりやすいブログなので参考にしてください。

https://shimooka.hateblo.jp/

# クラス書き方
クラスを書いていきます。***クラス名は大文字スタート***です。

```php
<?php

class Goods{
   
//アクセス修飾子protected(自分で継承したクラス)

 
//変数
private $goods = [];

//関数
function __construct($goods){
    $this->goods = $goods;
}

public function getGoods(){
    echo $this->goods;
}

public function addGoods($item){
    $this->goods .= $item;
}


public static function  getStaticGoods($str) {
    echo $str;
}


}

$instance = new Goods("練習");

var_dump($instance);
//object(Goods)#1 (1) { ["goods":"Goods":private]=> array(0) { } }

echo "<br>";

$instance->getGoods();
echo "<br>";

$instance->addGoods("追加");
echo "<br>";

$instance->getGoods();
echo "<br>";


Goods::getStaticGoods("静的");
echo "<br>";


//object(Goods)#1 (1) { ["goods":"Goods":private]=> string(6) "練習" }
//練習

//練習追加
//静的
```
```this```は***このクラス***という意味です。***this***は```goodsクラス```を指しています。
```->はアロー関数```のことで、***変数やメソッドを呼び出し***ます。

クラスの中で***変数名を定義***する時は```private```を使います。***外部からアクセスができなく***します。
クラスの中で***メソッド名を定義***する時は```public```を使います。これは***一般公開***できます。
```protected```は自分で継承したクラスのことです。

```__constructメソッド```は***引数で受け取った$goodsを代入***します。
クラスを初期化する時には```__constructor()```を使います。

```static```により、***静的に関数が使えます。***
使い方は```クラス名::関数名```です。


```new```で***クラス名を入れてインスタンス化***できます。

# 継承
```継承```とは***別のクラスを引き継ぐこと***です。
子クラスが親クラスの機能を継承していきます。子クラスの機能を継承していきます。

```php
<?php

//親クラス
class NewGoods{

public function echoGoods(){
    echo "親クラス";
}

}


//子クラス
class Goods extends NewGoods{   //親クラスを子クラスが継承
   
//アクセス修飾子protected(自分で継承したクラス)

 
//変数
private $goods = [];

//関数
function __construct($goods){
    $this->goods = $goods;
}

public function getGoods(){
    echo $this->goods;
}

public function addGoods($item){
    $this->goods .= $item;
}


public static function  getStaticGoods($str) {
    echo $str;
}


}

$instance = new Goods("練習");


echo "<br>";

$instance->getGoods();
echo "<br>";

//親クラスもメソッド
$instance->echoGoods();
echo "<br>";

$instance->addGoods("追加");
echo "<br>";


Goods::getStaticGoods("静的");
echo "<br>";

//練習
//親クラス

//静的
```

# オーバーライド
```オーバーライド```とは上書きのことです。

```php
<?php

//親クラス
class NewGoods{

public function echoGoods(){
    echo "親クラス";
}
//オーバーライド
public function getGoods(){
    echo "親の関数";
}

}

//子クラス
class Goods extends NewGoods{   //親クラスを子クラスが継承
   
//アクセス修飾子protected(自分で継承したクラス)

//変数
private $goods = [];

//関数
function __construct($goods){
    $this->goods = $goods;
}

// public function getGoods(){
//     echo $this->goods;
// }

public function addGoods($item){
    $this->goods .= $item;
}


public static function  getStaticGoods($str) {
    echo $str;
}

}

$instance = new Goods("練習");

echo "<br>";

$instance->getGoods();
echo "<br>";

//親クラスもメソッド
$instance->echoGoods();
echo "<br>";

$instance->addGoods("追加");
echo "<br>";

Goods::getStaticGoods("静的");
echo "<br>";

//親の関数
//親クラス

//静的
```

```final```というキーワードがあるのですが、これは***子クラスから上書きできない***です。

```php
//親クラス
class NewGoods{

public function echoGoods(){
    echo "親クラス";
}
//オーバーライド
public function getGoods(){
    echo "親の関数";
}


}


//子クラス
final class Goods extends NewGoods{   //親クラスを子クラスが継承
   
//アクセス修飾子protected(自分で継承したクラス)

 
//変数
private $goods = [];

//初回
function __construct($goods = null){
    $this->goods = $goods;
}

 final public function getGoods(){
     echo $this->goods;
 }

public function addGoods($item){
    $this->goods .= $item;
}

public static function  getStaticGoods($str) {
    echo $str;
}

}

$instance = new Goods("練習");


echo "<br>";

$instance->getGoods();
echo "<br>";

//親クラスもメソッド
$instance->echoGoods();
echo "<br>";

$instance->addGoods("追加");
echo "<br>";


Goods::getStaticGoods("静的");
echo "<br>";

//練習
//親クラス

//静的
```

## 補足
クラスの呼び方
***親クラス***を```基底クラス```または```スーパークラス```と呼び出す。
***子クラス***を```派生クラス```または```サブクラス```と呼びます。

# 抽象(abstract)クラス
```抽象クラス```とは***他のクラスに継承されることが前提としたクラス***です。インスタンスを生成することができません。

https://www.php.net/manual/ja/language.oop5.abstract.php

```php
<?php
//抽象クラス
abstract class AbstractGoods{

    public function echoGoods(){
        echo "親クラス";
    }
//オーバーライド
    abstract public function getGoods();
        
}

//具象クラス
class NewGoods{

public function echoGoods(){
    echo "親クラス";
}
//オーバーライド
public function getGoods(){
    echo "親の関数";
}

}

//子クラス
class Goods extends AbstractGoods{   //親クラスを子クラスが継承
   
//アクセス修飾子protected(自分で継承したクラス)

//変数
private $goods = [];

//初回
function __construct($goods = null){
    $this->goods = $goods;
}

public function getGoods(){
     echo $this->goods;
 }

public function addGoods($item){
    $this->goods .= $item;
}

public static function  getStaticGoods($str) {
    echo $str;
}

}

$instance = new Goods("練習");


echo "<br>";

$instance->getGoods();
echo "<br>";

//親クラスもメソッド
$instance->echoGoods();
echo "<br>";

$instance->addGoods("追加");
echo "<br>";


Goods::getStaticGoods("静的");
echo "<br>";

//練習
//親クラス

//静的
```

# インターフェース


https://www.php.net/manual/ja/language.oop5.interfaces.php

```implements```をインターフェースを使う時によく使います。


```php
<?php

//インターフェース
interface  InterfaceGoods{

//     public function echoGoods(){
//         echo "親クラス";
//     }

public function getGoods();
        
}


//インターフェース
interface  NewsInterface{

    //     public function echoGoods(){
    //         echo "親クラス";
    //     }
    
    public function getNews();
            
}


//具象クラス
class NewGoods{

public function echoGoods(){
    echo "親クラス";
}
//オーバーライド
public function getGoods(){
    echo "親の関数";
}

}

//子クラス
class Goods implements GoodsInterface,NewInterface{   //親クラスを子クラスが継承
   
//アクセス修飾子protected(自分で継承したクラス)

 
//変数
private $goods = [];

//初回
function __construct($goods = null){
    $this->goods = $goods;
}

public function getGoods(){
     echo $this->goods;
 }

public function addGoods($item){
    $this->goods .= $item;
}


public static function  getStaticGoods($str) {
    echo $str;
}


}

$instance = new Goods("練習");


echo "<br>";

$instance->getGoods();
echo "<br>";

//親クラスもメソッド
$instance->echoGoods();
echo "<br>";

$instance->addGoods("追加");
echo "<br>";


Goods::getStaticGoods("静的");
echo "<br>";

//練習
//親クラス

//静的
```

# トレイト
```trait```はいくつかの機能をまとめるためのものです。

https://www.php.net/manual/ja/language.oop5.traits.php

```php
<?php

trait GoodsTrait{
    public function getGoods(){
        echo "商品";
    }
}

trait NewsTrait{
    public function  getNews(){
        echo "新しいニュースです";
    }
}

class Goods{

    use GoodsTrait;
    use NewsTrait;

    public function getInformation(){
        echo "クラスです。";
    }

    // public function getNews(){
    //     echo "クラスニュースです。";
    // }

    
}

//呼び出し
$goods = new Goods();

$goods->getInformation();
echo "<br>";
$goods->getGoods();
echo "<br>";
$goods->getNews();
echo "<br>";

//クラスです。
//商品
//新しいニュースです

```

ちょっと変えてみます。getNewsでクラスのニュースが優先されます。

```php
<?php

trait GoodsTrait{
    public function getGoods(){
        echo "商品";
    }
}

trait NewsTrait{
    public function  getNews(){
        echo "新しいニュースです";
    }
}

class Goods{

    use GoodsTrait;
    use NewsTrait;

    public function getInformation(){
        echo "クラスです。";
    }

     public function getNews(){
         echo "クラスニュースです。";
     }

    
}

//呼び出し
$goods = new Goods();

$goods->getInformation();
echo "<br>";
$goods->getGoods();
echo "<br>";
$goods->getNews();
echo "<br>";


//クラスです。
//商品
//新しいニュースです
```


# クラスと抽象クラスとインターフェースとトレイトを表にまとめる
上の4つを表にまとめてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/c919b5eb-bea0-c041-403f-69fa84d18f4f.png)
>引用　　https://qiita.com/MiyakeNatsuho/items/f2d42df417f5f56dd541


より詳細に載っています。

https://coinbaby8.com/php-class-abstract-interface-trait-di.html

https://qiita.com/MiyakeNatsuho/items/f2d42df417f5f56dd541




# 参考資料
下の講座を参考にしています。
実際動画の方がわかりやすいので購入してみてください。

https://www.udemy.com/course/phpbeginnertolaravel/

https://qiita.com/Hashimoto-Noriaki/items/cdd51704fb0a931bea55

https://techacademy.jp/magazine/26798

https://qiita.com/tkek321/items/a6112bc195b73438a9b0