익명 클래스
익명 클래스 (Anonymous classes)
단순하고 한 번만 쓰고 버릴 객체가 필요할 때는 익명 클래스가 특히 유용해요. 클래스에 이름을 붙이는 대신 new class로 바로 객체를 만들 수 있죠. 아래 예제는 똑같은 로거 객체를 명시적 클래스로 만든 경우와 익명 클래스로 만든 경우를 나란히 보여 줘요.
<?php
// Using an explicit class
class Logger
{
public function log($msg)
{
echo $msg;
}
}
$util->setLogger(new Logger());
// Using an anonymous class
$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 프로퍼티를 쓰고 싶다면 그 값을 생성자를 통해서 넘겨받아야 해요.
<?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
같은 익명 클래스 선언으로 만든 객체들은 전부 저 클래스의 인스턴스예요.
<?php
function anonymous_class()
{
return new class {};
}
if (get_class(anonymous_class()) === get_class(anonymous_class())) {
echo 'same class';
} else {
echo 'different class';
}
위 예제를 실행하면 이런 결과가 나와요.
same class
> 위 예제를 실행하면 이런 비슷한 결과가 나와요. ```php class@anonymous/in/oNi1A0x7f8636ad2021 ``` ## 읽기 전용 익명 클래스 PHP 8.3.0부터는 익명 클래스에 `readonly` 수식어를 붙일 수 있어요. **예제 #1 읽기 전용 익명 클래스 정의하기** ```php prefix . ' ' . $msg; } }); ```참고: 익명 클래스에는 엔진이 자동으로 이름을 붙여요. 아래 예제에서 그 모습을 확인할 수 있는데, 이 이름은 구현 세부 사항이니 프로그램에서 의존하면 안 돼요.