Вложенные анонимные классы в php 7

В общих чертах обьявление анонимного вложенного класса выглядит следующим образом:

 
class main {
	/**
	* обьявленные свойства и методы
	*/
	public function nestedClass('argument') {
		return new class('argument') extends main {
			/**
			* обьявленные свойства и методы
			*/
		}
	}
}

return и анонимный класс

Первое, что необходимо сделать, это вернуть анонимный класс в методе, определенном в базовом классе.

 
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 не доступен вложенному классу, поэтому любые изменения приватного свойства не будут видны базовому классу.

Также стоит упомянуть, что изменение видимости метода вложенного класса из публичного в приватный, делает его приватным, так что только базовый класс может получить к нему доступ.

Вывод

Как вложенные анонимные классы будет использоваться разработчиками, я не могу сказать. Но будет интересно посмотреть что с ними будут делать.

Теги:

php php7