PHP7から使えるという無名クラス、なんとクラスの定義をすることなくインスタンス(オブジェクト)を生成できる機能のようです。
new classで インスタンスを生成します。
⇩ 無名クラスについては下記サイトへ
・PHP 7 の無名クラスから考えるクラスの在り方 - Shin x Hatena Blog
PHPマニュアル(PHP: 無名クラス - Manual )によると
無名クラス
PHP 7 で、無名クラスをサポートするようになりました。
その場限りの使い捨てのオブジェクトが必要になった場合に便利です。
<?php
// PHP 7 より前のバージョンのコード
class Logger
{
public function log($msg)
{
echo $msg;
}
}
$util->setLogger(new Logger());
// PHP 7 以降のコード
$util->setLogger(new class {
public function log($msg)
{
echo $msg;
}
});
コンストラクタを使って引数を渡したり、他のクラスを継承したり、 インターフェイスを実装したり、トレイトを使ったりといった、 普通のクラスと同じようなことが可能です。
<?php
class SomeClass {}
interface SomeInterface {}
trait SomeTrait {}
var_dump(new class(10) extends SomeClass implements SomeInterface {
private $num;
public function __construct($num)
{
$this->num = $num;
}
use SomeTrait;
});
上の例の出力は以下となります。
object(class@anonymous)#1 (1) { ["Command line code0x104c5b612":"class@anonymous":private]=> int(10) }
無名クラスを別のクラス内で作っても、外側のクラスの private や protected なメソッドそしてプロパティにはアクセスできません。
外側のクラスの protected プロパティやメソッドにアクセスするには、 無名クラスに外側のクラスを継承させます。
外側のクラスの private あるいは protected なプロパティを無名クラスで使うには、 コンストラクタでそれを渡す必要があります。
<?php
class Outer
{
private $prop = 1;
protected $prop2 = 2;
protected function func1()
{
return 3;
}
public function func2()
{
return new class($this->prop) extends Outer {
private $prop3;
public function __construct($prop)
{
$this->prop3 = $prop;
}
public function func3()
{
return $this->prop2 + $this->prop3 + $this->func1();
}
};
}
}
echo (new Outer)->func2()->func3();
上の例の出力は以下となります。
6
クラスの役割とは
『コーディングを支える技術 ~成り立ちから学ぶプログラミング作法 (WEB+DB PRESS plus) 単行本(ソフトカバー) – 2013/4/24 西尾 泰和 (著)』によると、
『クラスには2つの相反する役割があります。
1つ目は「インスタンスを作るためのもの」という役割で、このためには
「完結した、必要なものを全部持った、大きなクラス」
である必要があります。
2つ目は「再利用の単位」という役割で、このためには
「機能ごとの、余計なものを持っていない、小さなクラス」
である必要があります。
クラスが「インスタンスを作るためのもの」として使われているときには、再利用の単位としては大きすぎるのです。』
PHP5.4から導入されたトレイトは、コードを再利用するためのしくみなので、まさにこの「再利用の単位」という 役割を担っているといえます。
また、インターフェイスは、関数の引数を特定の型に限定できるタイプヒンティング(型宣言)に指定できるので 、クラスに型が必要なときは、インターフェイスを使うのが好ましいようです。
無名クラスに、トレイトやインターフェイスを使っていくことで、これまでのクラスの定義の複雑さが解消されていくような感じでしょうか。
主に、インターフェイスで「仕様」を定義し、トレイトで「実装」し、必要な時に無名クラスで利用するのが、PHP7のトレンドになっていくんではなかろうかとのことらしいです。
また、無名クラスとは関係ないかもしれませんが、仕様と実装を分離するという点では、下記の情報によるとポリモーフィズムもどうなんでしょうと。
仕様と実装を分離することによって主に拡張性を高めることを目的としています。
たとえば、親クラスにおいて仕様、つまりメソッドのみを宣言し、その親クラスによって宣言されたメソッドを子クラスにおいて実装することで仕様と実装を分離することができます。
このポリモフィズムによって親クラスに変更を加えなくても、子クラスを取り替えることで内部実装を柔軟に交換することが可能となっています。
⇩ ポリモーフィズムやタイプヒンティング、インターフェイスなどは下記サイトへ
・PHPのオブジェクト指向入門 | オブジェクト指向PHP.NET
今回はこのへんで。