В других ответах уже упоминалось Late-Static-Binding как решение вашей проблемы, и это действительно ответ, но никто не реализовал его правильно, а некоторые ответы были слишком сложными.
Статическая переменная предназначена для того, чтобы быть доступной для всех экземпляров или статических обращений к классу в прямом направлении.Итак, как вы сказали в своем коде, Man переписывал значение, установленное Dog, потому что ваша статическая переменная была установлена в родительском классе «Animal», и поэтому была доступна для каждого дочернего класса. Каждый дочерний класс имеет доступ и поэтому может перезаписывать в любой точке.
Позднее статическое связывание решает эту проблему, позволяя вам иметь несколько объявлений вашей статической переменной в дочерних классах вместо родителя,но все же позволяя родительскому классу работать со статической переменной, объявленной дочерним классом.
Вот ваш код, правильно использующий позднюю статическую привязку.
<?php
class Animal {
public static function Walk() {
return 'Takes a step with ' . static::$numLegs . ' legs.'; //the 'static' keyword lets you operate on child classes' static vars
}
}
class Dog extends Animal {
static public $numLegs; //dog has its own static var
public static function Init() {
self::$numLegs = 4;
}
}
class Man extends Animal {
static public $numLegs; //man has its own static var
public static function Init() {
self::$numLegs = 2;
}
}
Dog::Init();
Man::Init();
echo 'The dog walks: ' . Dog::Walk(); //The dog walks: Takes a step with 2 legs.
echo 'The man walks: ' . Man::Walk(); //The man walks: Takes a step with 2 legs.
?>
И результат:
Собака ходит: делает шаг с 4 ногами. Человек идет: делает шаг с 2 ногами.