クラスとインスタンス

いまいち理解しきれてないクラスとインスタンス。
データベースとの接続や、jQueryで頻繁に使われているので、もう一度ちゃんと整理。

##オブジェクト指向について

オブジェクト指向とは、共通で処理できるところは一括しておき、あとは個別のページごとに必要な個別処理を追記していくこと。
開発しているページなどが、数ページにわたる大規模なモノになると、共通処理クラスをまとめておかないと、各ページに乱立することになる。

##クラスとインスタンスについて

###クラス

大まかな設計図。オブジェクトを抽象化したもの。

####クラスの作り方

```php
Class クラス名　←クラス名宣言（基本クラス名の一文字目は大文字）
{
 public $変数 ="文字列";　←メンバーの設定（変数のみでも構わない。文字列は初期値）

 public function 関数名(){　←メソッドの定義

 }
}
```

クラス内で作成した関数をメソッド。
変数をプロパティという。

###インスタンス

実体化したもの。設計図をもとに設計した、個別に特徴があるデータ。

####インスタンスの作り方

インスタンスを作る際には、new演算子を用いて、作成する。

```php
Class クラス名
{
 public $変数 ="文字列";

 public function 関数名(){

 }
}

$西村 = new クラス名();

$西村->変数名 = "西村";←プロパティの手前に$はいらない。

echo $西村->変数名;
```

###クラスとインスタンスの例

```php
Class Car
{
 public $color ="塗装前";
 public $speed ="0"

 public function run(){
   print "{this->color}車で、時速{$this->speed}kmで走行します。";
 }
}


$myCar = new Car();

$myCar = run();←設定したインスタンスでメソッドを実行（車を走らせる）

$myCar->color = "赤い";
$myCar->speed = 20;

echo $西村->変数名;
```

結果)赤い車で、時速0kmで走行します。

▶new演算子

クラスのインスタンスを作成するために必須の合言葉。

```php
$インスタンス名 = new クラス名();
```

▶**`$this`**

$thisは、メソッドの中から、メンバーアクセスにアクセスすることのできる疑似変数。
例えば、

```php
Class Car
{
 public $color ="塗装前";
 public $speed ="0"

 public function run(){
   print {$this->color}."車で、時速".{$this->speed}."kmで走行します。";
 }
}
```

このように、クラス内の変数に初期値が渡されていて、それを呼び出したい場合に、`{$this->speed}`のような形にしておくことができる。

▶アロー演算子**->**

アロー演算子は、「クラス」や「オブジェクト」に必要な演算子。

左辺の情報を、右辺に各イメージ。
例えば、例の

```php
$myCar ->color = "赤い";
```

だと、インスタンスであるmyCarの中の、変数colorの情報をだけを取り出して、イコールでそれが何なのか具体的に提示しているイメージ。

###コンストラクトとは

コンストラクトとは、インスタンスを作成した際に自動で実行される関数のこと。
コンストラクトが無くても、クラスは成り立つ。
何が得かというと、引数をまとめておくことができるので、いちいちアロー演算子で指定せずに済むこと。一回の指定で済む。
上記と比較すると、一番下の変数の呼び出しがスマートにまとまってる。new演算子だけでいい。

```php
Class Car
{
 public $color ="塗装前";
 public $speed ="0";

 public function __construct($color,$speed){

 $color = $this -> color; ←ここで、もし$プロパティcolorの初期値が、上記のように木間てっているなら、初期値がセットされる。
　↑この$colorはconstructの後にあるやつ
 $speed = $this -> speed;

}

 public function run($color,$speed){
   print $color."車で、時速".$speed."kmで走行します。";
 }
}


$myCar = new Car;　←インスタンスの情報を一括定義

echo $myCar -> run(赤い,120); ←インスタンスからの関数の呼び出し

```

##クラス継承
継承とは、新たにクラスを作成するときに、他のクラス内の内部データや関数を引き継ぐこと。
継承されるクラスのことは**スーパークラス（親クラス）**
継承するクラスのことは**サブクラス（子クラス）**と呼ぶ。

###`extends`
構文には`extends`を使用する。

```php
class 新しいクラス名 extends 継承するクラス名{

}
```
＊`extends`を付け加えることで、基本的にすべてのメンバーを引き継ぐことになるが、**private修飾子による権限が指定されている場合のみ、引き継げない。**

###OverRide(再定義)

子クラスが、親クラスと同名の関数を上書きすることを、OverRideという。

```php
class Car
{
 public $color ="塗装前";
 public $speed ="0";

 public function __construct($color,$speed){

 $color = $this -> color;
 $speed = $this -> speed;

}

 public function run($color,$speed){
   echo $color."車で、時速".$speed."kmで走行します。";
 }



}
class Bike extends Car{ ///継承クラス
 public function run($color,$speed){///override
 echo $color."バイクで、時速".$speed."kmで走ります。";
}
}

$myCar = new Car;
echo $myCar -> run(赤い,120);

$myBike = new Bike;
echo $myBike -> run(緑の,150);
```

###`final`

`final`は、クラスの継承や、オーバーライドを禁止するキーワードのこと。
特に、記述に関して注意する点はない。例は下記の通り。

```php
class A{
 final public function B{

}

final class C{

}
}
```

##抽象クラスとインターフェイス

###抽象クラス

###インターフェイス

クラスに必ず実装させたいメソッドを指定して、実装漏れをなくすことのできるキーワード。
特徴としては、

- 定義できるのは中小メソッドのみ
- 抽象メソッドだが、`abstract`はいらない。
- アクセス修飾子は、`public`しか指定できない
- 直接インスタンスの生成はできない。


##静的メソッド

###staticキーワード
クラスのメンバへ、インスタンスを作成しないでもアクセス可能なメソッドのこと。
**`static`**を用いることで、静的メソッドを作り出すことができる。
擬似変数`$this`は使用することができない。
また、インスタンス化しないので、変数を用いることもできない。

####staticメソッド

```php
<?php

class Practice {
  public static function aPracticeMethod(){
    echo "foo";
  }
}

Practice::aPracticeMethod(); //正常に作動

$Practice = "Foo";
$Practice::aPracticeMethod(); //エラー、変数はエラーになる。
?>
```

####staticプロパティ

```php
<?php

class Practice {
  public static $name = "名無し";
}

echo Practice::$name;
```

###スコープ演算子（::）
スコープ演算子は、

###PHPの動的と静的の違いについて

- 動的：Dtnamic
- 静的：Static
変化がないこと。
PHPでは、クラスに属しているオブジェクトのようなイメージでおk。
例えば、

```php
<?php

class Practice {
  public $name = "名無し";
}

$a = new Practice();

echo $a -> name;
```

普通のクラスとインスタンスの関係だと、クラスからインスタンスを生成することで、その内部にある変数やメソッドにアクセスするという感じだけれど、
staticを使うとそれができなくなる。


```php
<?php

class Practice {
  public static $name = "名無し";
}

$a = new Practice();

echo $a -> name;

```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/266350/ac7135ae-ea55-2717-c960-7dc9331af74a.png)

おそらく、変動しない＝完全にクラスに属した存在になる
そんなイメージ...なのか？

###`self::`

`self::`は言うたらstatic版の`$this->`
スコープ内のスタティックプロパティなんかにアクセスするための奴。


```php
<?php

class Practice {
  public static $name = "名無し";

  public function Foo(){
    echo self::$name;
  }
}

$a = new Practice();

$a ->Foo();
```

###`parent::`

`parent::`は、親クラスのプロパティにアクセスする際に使用する`$this`みたいな感じ。

```php
<?php

class Practice {
  public static $name = "名無し";

  public function Foo(){
    echo self::$name;
  }
}

class Child extends Practice {
  public function foo(){
    echo parent::$name;
  }
}

$b = new Child();

$b -> foo();
```

##アクセス権
アクセス権とは、メンバ変数やメソッドにどこからアクセスできるか決めるもの。

主に、

- public...どこからでもアクセス化
- private...同じクラス内からアクセス化
- public...同じクラス内、子クラスからアクセス化

の３つがある。
protectedはクラス継承時のみ、関係してくるアクセス権になる。

publicとprivateの違いは、クラス外のインスタンスからアクセスできるのか、できないのかという点で簡単に説明できる。
例として、

```php
class Car
{
 public $color ="塗装前";
 public $speed ="0";

 public function __construct($color,$speed){

 $color = $this -> color;
 $speed = $this -> speed;

}

 public function run($color,$speed){
   echo $color."車で、時速".$speed."kmで走行します。";
 }
 private function walk($color,$speed){
   echo $color."靴で、時速".$speed."mで走行します。";
 }
}

$myCar = new Car;
echo $myCar -> run(赤い,120);
$myCar = new Car;
echo $myCar -> walk(赤い,120);
```

上記では、`private function walk`メソッドを設定している。
インスタンスからこの関数を呼び込もうとしているが、呼び込めない。

```php
class Car
{
 private $color ="塗装前";
 public $speed ="0";

 public function run(){

 $color = $this -> color;
 $speed = $this -> speed;

}
}

$myCar = new Car;
echo $myCar->color;
echo $myCar->speed;

```
また上記のように、変数をprivateに設定しても、呼び出すことはできない。
ただし、privateに設定した変数が、クラス内の関数で呼び出しを受けた状態で、インスタンスから呼び出しを受けると、普通に表示される。
下記のような状態。

```php
class Car
{
 private $color ="塗装前";
 public $speed ="0";

 public function __construct($color,$speed){

 $color = $this -> color;
 $speed = $this -> speed;

}

 public function run($color,$speed){
   echo $color."車で、時速".$speed."kmで走行します。";
 }

}

$myCar = new Car;
echo $myCar -> run(赤い,120);
```
上記のように、クラス内でいったんメソッドを通しているものに関しては、インスタンスからの呼び出しにも応じてくれる。

##外部ファイルへのアクセス

他のファイルからのデータを取得して出力したいときなどには、以下のキーワードを使う。

|キーワード名   |役割
|:-------------|:---------------------------
|require       |エラーが発生した瞬間に、処理を中止する。
|require_once  |ファイルが既に読み込まれている場合、再読み込みしない。
|include       |エラーが発生したら、警告文を出し、処理は続行する。
|include_once  |ファイルが既に読み込まれている場合、再読み込みしない。
|autoload      |
構文は

```php
require_once 'ファイル名';
```

これだけで、他のファイルを読み込むことができる。

##名前空間
名前の重複を避けることを目的としたもの。
この名前とは、クラス名、インターフェイス名、、関数名、定数名のこと。
複数人で大規模な開発などを行っているときに、名前が被り関数などが呼び出せないときがある。その時に名前空間を設定しておく。

イメージは、ファイルに格納するイメージ。ファイルが違えば、同名のデータでも「名前が被っています」という注意文が出ないのと一緒。

ex)sample01.phpというファイルと、sample02.phpというファイル、
この2つのファイルを呼び出して、データを出力するrequire.phpという3つのファイルがある。sample01とsample02には、同名のクラスや関数が存在している。これを呼び出そうとすると、

sample01.php

```php
<?php

class Car{

  function run(){

    echo "booon!!";
  }

}

?>
```

sample02

```php
<?php

class Car{

  function run(){

    echo "booon!!";
  }

}

?>
```

require.php

```php
<?php

ini_set('display_errors', "On");

require_once 'sample01.php';
require_once 'sample02.php';

$bmw = new Car;
$bmw ->run();

?>
```

![スクリーンショット (12).png](https://qiita-image-store.s3.amazonaws.com/0/266350/63825637-d2ee-77d2-0b73-3aa7951629c7.png)

上記のようになる。
これを名前空間を設定することにより避ける。

sample01

```php
<?php
namespace Japan;

class Car{

  function run(){

    echo "booon!!";
  }

}

?>
```
sample02

```php
<?php
namespace Usa;

class Car{

  function run(){

    echo "booon!!";
  }

}

?>
```

require.php

```php
<?php

ini_set('display_errors', "On");

require_once 'sample01.php';
require_once 'sample02.php';

$bmw = new Japan\Car;
$bmw ->run();
$bmw = new Usa\Car;
$bmw ->run();

?>

```

名前空間を設定したことで、2つの同名のクラスを区別することができ、下の画像のように、正しく出力される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/266350/ec060f3e-a69f-a11d-3b74-31b4dee38f0f.png)

###useキーワード
もし、名前空間の指定が長すぎる場合は、`use`で省略することができる。

```php
use 名前空間の全て、または一部 as 別名;
```

useの後に記述する名前空間は完全修飾形式で記述する。

▶完全修飾形式とは？

#参考資料

- static

http://restart404.hatenablog.com/entry/2017/05/29/235942
http://restart404.hatenablog.com/entry/2017/05/29/235942