В качестве особого примечания, родительский класс должен иметь свойство, определенное для того, чтобы этот метод работал, в противном случае, если класс Mommy не имеет $ _data, определенную как свойство, выдается фатальная ошибка при попытке повторно указать Ссылка на дочернее свойство с $ selectedClass :: $ _ data = & $ data ;. (Это потому, что дочерний класс никогда не наследует указатель от родительского, поэтому он не может переназначить указатель на что-либо.) Это отличается от явного определения его в дочернем классе без обходного пути - он не требует его в родительский класс при определении его непосредственно в дочернем классе.
трите на этот пример и обратите внимание на указанные результаты.
<?php
class Mommy
{
protected static $_data = "Mommy Data";
public static function init( $data )
{
static::$_data = $data;
}
public static function showData()
{
echo static::$_data . "<br>";
}
}
class Brother extends Mommy
{
}
class Sister extends Mommy
{
}
Brother::init( "Brother Data" );
Sister::init( "Sister Data" );
Brother::showData(); // Outputs: Sister Data
Sister::showData(); // Outputs: Sister Data
?>
Насколько я понимаю, с помощьюстатический Ключевое слово будет ссылаться на дочерний класс, но, очевидно, оно волшебным образом применяется к родительскому классу всякий раз, когда оно отсутствует в дочернем классе. (Это довольно опасное поведение для PHP, подробнее об этом будет сказано ниже.)
Я имею в виду следующие две вещи, почему я хочу сделать это:
Я не хочу избыточности определения всех свойств во всех дочерних классах.Я хочу, чтобы свойства определялись как значения по умолчанию в родительском классе, и я хочу, чтобы определение дочернего класса могло переопределять эти свойства везде, где это необходимо. Дочерний класс должен исключать свойства всякий раз, когда заданы значения по умолчанию, поэтому я не определяю свойства в дочерних классах в приведенном выше примере.Однако, если мы хотим переопределить свойство во время выполнения (через метод init), оно переопределит его для родительского класса! С этого момента дочерние классы, инициализированные ранее (как в случае с Brother), неожиданно изменяются на вас.
По-видимому, это результат того, что дочерние классы не имеют своей собственной копии статического свойства, если оно явно не определено внутри дочернего класса - но вместо того, чтобы выдавать ошибку, оно переключает поведениестатический чтобы получить доступ к родителю. Следовательно,есть ли способ, которым родительский класс мог бы динамически создать свойство, которое принадлежит дочернему классу, без его появления в определении дочернего класса? Таким образом, дочерний класс может иметь свою собственную копию статического свойства, и ключевое слово static может ссылаться на него должным образом, и его можно записать с учетом значений по умолчанию родительского свойства.
Или есть какое-то другое решение, хорошее, плохое или безобразное?