В общих чертах обьявление анонимного вложенного класса выглядит следующим образом:
class main {
/**
* обьявленные свойства и методы
*/
public function nestedClass('argument') {
return new class('argument') extends main {
/**
* обьявленные свойства и методы
*/
}
}
}
Первое, что необходимо сделать, это вернуть анонимный класс в методе, определенном в базовом классе.
class main {
public $ publicProp = 'public';
protected $ protectedProp = 'Protected';
private $ privateProp = 'private';
public function nestedClass() {
return new class() extends main {
public $ nestedProp = 'Nested';
};
}
};
$object = (new main)->nestedClass ();
echo $object->nestedProp; // Nested
echo $object->publicProp; // Public
В приведенном выше примере, класс main содержит метод nestedClass который возвращает вложенный анонимный класс. Следует отметить, что вложенный класс расширяет класс main. Это дает ему доступ к защищенным (protected) и публичным (public) свойствам и методам базового класса. Однако приватные (private) свойства и методы не доступны.
Для доступа к защищенным свойствам вне класса, мы можем определить метод, который вернет его. Этакий геттер для анонимного класса.
class main {
public $ publicProp = 'public';
protected $ protectedProp = 'Protected';
private $ privateProp = 'private';
public function nestedClass() {
return new class() extends main {
public $nestedProp = 'Nested';
public function returnProtected(){
return $this->protectedProp;
}
};
}
};
$object = (new main)->nestedClass ();
echo $object->nestedProp; // Nested
echo $object->publicProp; // Public
echo $object->returnProtected(); // Protected
Поскольку приватные свойства базового класса не видны в классах - наследниках, такие свойства должны быть переданы в анонимный класс как аргументы конструктора для создания нового свойства.
class main {
public $ publicProp = 'public';
protected $ protectedProp = 'Protected';
private $ privateProp = 'private';
public function nestedClass() {
return new class( $this->privateProp ) extends main {
public $nestedProp = 'Nested';
public $newProp;
public function __construct( $property ) {
$this->newProp = $property;
}
public function returnProtected(){
return $this->protectedProp;
}
};
}
};
$object = (new main)->nestedClass ();
echo $object->nestedProp; // Nested
echo $object->publicProp; // Public
echo $object->returnProtected(); // Protected
echo $object->newProp; //Private
Разберем подробно код выше. В базовом классе мы обьявили приватное свойство $privateProp, его, в качестве аргумента, мы передали в конструктор вложенного анонимного класса.
В конструкторе анонимного класса мы присвоили приватное свойство родительского класса, переменной, обьявленной внутри вложенного класса. Так же реализовали метод доступа к данному свойству.
Переменную, которую предполагается использовать для хранения приватного свойства родителя, можно обьявить и приватной и защищенной - все зависит от потребностей
Важно понимать, что публичные и защищенные, свойства и методы базового класса доступны для вложенного класса до тех пор, пока он расширяет бызовый класс. Приватные свойства и методы базового класса не будут видны и не будут доступны вложенному классу.
В последнем примере я показал как можно передать приватные свойства, однако статический доступ к свойству main:: privateProp не доступен вложенному классу, поэтому любые изменения приватного свойства не будут видны базовому классу.
Также стоит упомянуть, что изменение видимости метода вложенного класса из публичного в приватный, делает его приватным, так что только базовый класс может получить к нему доступ.
Как вложенные анонимные классы будет использоваться разработчиками, я не могу сказать. Но будет интересно посмотреть что с ними будут делать.