トレイト
トレイト → 意味:特性
別のクラスに、あたかもコピーペーストするように差し込むことができる。
トレイトはインスタンス化はできない。
trait [ トレイト名 ] { トレイトの中身を記述 }
トレイトをクラスに差し込むには、差し込まれる側のクラスに use キーワード使用。
use [ トレイト名1 ] , [ トレイト名2 ] . . . ;
FILE_APPEND
filenameがすでに存在する場合に、 データをファイルに上書きするするのではなく追記します。
□プロパティ名、メソッド名のバッディングを解決する□
複数のトレイトを use で読み込むときは、プロパティ名とメソッド名がバッディングしないようにする。
<?php declare(strict_types=1); ?>
<body>
<?php
require_once dirname(__FILE__) . '/SomeTraitA.php';
require_once dirname(__FILE__) . '/SomeTraitB.php';
class SomeClass
{
use SomeTraitA, SomeTraitB;
public function setTraitProperty()
{
// トレイトが持つtraitMethod()がわからない。
$this->traitMethod(NULL, NULL);
print $this->traitProperty;
}
}
$someClass = new SomeClass();
$someClass->setTraitProperty();
?>
</body>
<?php
declare(strict_types=1);
trait SomeTraitA
{
private $traitProperty;
public function traitMethod($argsl, $args2)
{
$this->traitProperty = 'A';
}
}
<?php
declare(strict_types=1);
trait SomeTraitB
{
private $traitProperty;
public function traitMethod($argsl, $args2)
{
$this->traitProperty = 'B';
}
}
いずれのトレイトにも、同名のtraitMethod() というメソッドが定義されている。
どちらのメソッドを呼び出せばいいか判断がつかないためエラーになる。
プロパティ$traitProperty も2つのトレイトで名前がバッディングしている。
これは初期値が代入されていないためエラーにはならない。
いずかれの$traitProperty = 1 ;
のように初期化があるとどちらの初期値を正とすべきかの判断ができなためエラーになる。
これらの問題を解消するのが → insteadof キーワード
use トレイト1, トレイト2
{
使うトレイト名 : : 使うトレイトメソッド insteadof 使わないトレイト名 ;
}
SomeTraitA の TraitMethod を setA というメソッド名で使えるようにする
asキーワード使用する。
<?php declare(strict_types=1); ?>
<body>
<?php
require_once dirname(__FILE__) . '/SomeTraitA.php';
require_once dirname(__FILE__) . '/SomeTraitB.php';
class SomeClass
{
use SomeTraitA, SomeTraitB
{
SomeTraitB::traitMethod insteadof SomeTraitA;
// SomeTraitA の traitMedthod を使うときは setAと別名を使う。
SomeTraitA::traitMethod as setA;
}
public function setTraitProperty()
{
$this->traitMethod(NULL, NULL);
print $this->traitProperty . PHP_EOL;
$this->setA(NULL, NULL);
print $this->traitProperty . PHP_EOL;
}
}
$someClass = new SomeClass();
$someClass->setTraitProperty();
?>
</body>
トレイトとクラスは密な関係をも生む。
プロパティを変更したらどっちも変えないといけなくなる。
トレイトはプログラムの見通しを悪くするため使うべき積極的な場面理由があるかをよく考えたうえで使う。
interface
インターフェースはルールに従っていることを約束させるために使う。
◎例:
自転車 ・ 自動車 2つのクラスがったとする。
乗り物として「走る」点では一緒。しかし、内部の作りはまったく異なるもの。
1,自動車 → エンジン
2,自転車 → ペダル
持っているプロパティ、メソッドの内部処理が異なっている → 2つのクラスを継承でまとめるのは少し無理がある。
このような、できること(メソッド名、引数、戻り値)のみが同じで、中身が異なる2つ以上のクラスを統一的に扱うのが → インターフェース(特別な抽象クラス)
具体的なプログラム処理が書かれた具象メソッドや、プロパティを持つことができない。
インターフェースは、
その実装クラスが持つべきメソッドの仕様(メソッド名、引数、戻り値)を示すことに特化したもの。その内部処理にまでは介入しない。
介入してしまうと、、、
[ USBキーボード、USBカメラ、USB扇風機 ]
できることは同じ → 中身が全く違う
これができない。幅広く作れなくてできない。
インターフェース → 実装する。
継承 → 子クラスが親クラスを継承する。
□ インターフェースの実装 □
◎インターフェースを定義
interface [ インターフェース名 ]
◎インターフェースの抽象メソッドを定義
pubic function [ メソッド名 ]( [引数] , [引数] )
インターフェースは、class の代わりに interface を定義。
インターフェース内に定義する
抽象メソッド → abstract を省略する。
インターフェースには public しか定義できない → 具体的なプログラム処理にまでは介入しない性質のため。
◎インターフェースを実装
class [ クラス名 ] implements [ インターフェース名 1] , [ インターフェース2 ] …
<?php declare(strict_types=1);
require_once dirname(__FILE__) . '/Flyable.php'; // 飛ぶファイル
class Airplane implements Flyable
{
// 飛ぶメソッド
public function fly() : void
{
print '飛びます<br>';
}
}
<?php declare(strict_types=1); ?>
<body>
<?php
///////////////////////////////////////////////////////
//
// メインルーチン 2
//
//////////////////////////////////////////////////////
require_once dirname(__FILE__) . '/Sky.php';
require_once dirname(__FILE__) . '/Bird.php';
require_once dirname(__FILE__) . '/Airplane.php';
// 空インスタンス
$sky = new Sky();
// 鳥インスタンス
$bird = new Bird();
// 飛ぶインスタンス
$airplane = new Airplane();
// 鳥の状態
$sky->draw($bird);
$sky->draw($airplane);
?>
</body>
ーーーーコメント^^^^
オブジェクト指向でインターフェース、トレイト、as はあんま使わないかな?使うものなのか。。。とりあえずあることを知って良かった。
もうすこしでオブジェクト指向終わりそう。。
一番大事といってもいいぐらいだしねララベルも結局はクラスなんだしね、
この記事が気に入ったらサポートをしてみませんか?