@jeckhummer

Как правильно избавляться от связей с ненужными свойствами родительского класса внутри класса-наследника?

Класс А обладает приватным свойством $prop, которое инициализируется в конструкторе с помощью защищенного метода:

class A
{
	private $prop;
	...

	public function __construct(array &$config)
	{
		if (isset($config['prop'])) {
			$this->setProp($config['prop']);
		}
		...
	}

	protected function setProp($value)
	{
		$this->prop = $value;
	}
	...
}


Почему именно с помощью защищенного метода?
Например, я хочу, чтоб свойство $prop можно было задать извне (через конфигурационный массив) только один раз во время создания объекта класса. Если бы не protected, то метод setProp() - классический setter. Зачем он нужен? Для того, чтоб была возможность переопределить его в классе-наследнике B:

class B extends A
{
	// ...
	public function __construct(array &$config)
	{
		parent::__construct($config);
		// инициализация свойств характерных только для класса B
		// ...
	}

	final protected function setProp(){}
	// ...
}

Таким образом присвоение не произойдет.

Казалось бы, если не передавать в конфигурационном массиве not null элемент с ключом "prop", то и никакого вызова setProp() не будет.
Предположим, что этот массив требуется для инициализации нескольких объектов и создается одним способом и один раз. Такое ограничение оправдано, если получить значения для него - трудоёмкая задача (поэтому, кстати, в аргументе конструктора я передаю его по ссылке). Следовательно, каждый обьект, его использующий, должен взять от него только нужные данные. Тогда невозможность передавать в конструктор "правильный" массив становится обоснованной.

Еще в качестве решения можно предложить переписать конструктор в классе-потомке без использования родительского конструктора. Но, по-моему, это приведет к откровенной копипасте.
Можете ли подсказать лучшее решение, чем поставлять заглушку вместо метода в наследнике?

В принципе, меня не особо волнует, что в классе В есть какое-то ненужное свойство $prop (пусть даже инициализированное), если я его не использую. Но может все таки стоит волноваться? Кто нибудь встречался с какими нибудь проблемами или неудобствами в этом плане?
  • Вопрос задан
  • 275 просмотров
Решения вопроса 1
@serega_kaktus
Программист-самоучка, фрилансер
Если у вас свойство $prop приватно, то объявите setProp тоже приватным. Так ни метод ни свойство не будут доступны в классах-потомках.
Если же вы не знаете, будет ли свойство $prop использоваться в потомках, то лучше сделать его protected, как и метод setProp(). И не стоит тогда использовать final protected function setProp(), вы же не знаете, как это свойство может быть использовано в классе C extends B.

PS Стараюсь использовать protected свойства, так как это дает больше контроля над данными потомкам. При этом, если потомку какое либо свойство не нужно, он к нему просто не обращается.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
He11ion
@He11ion
PHP-monkey
unset($this->prop);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы