Stati c счетчик экземпляров подкласса в PHP - PullRequest
1 голос
/ 28 мая 2020

Мне известен шаблон для добавления счетчика stati c к классу для подсчета количества экземпляров этого класса

class Vehicle
{
  private static $_count=0;

  public static function getCount() {
    return self::$_count;
  }

  public function __construct()
  {
    self::$_count++;
  }
}

Я бы хотел добавить пару подклассов для Vehicle и подсчитывать экземпляры тех независимо

class Bike extends Vehicle
{
   ...
}

class Car extends Vehicle 
{
   ...
}

Таким образом, вызов Bike::getCount() и Car::getCount() приведет к подсчету количества велосипедов и автомобилей соответственно

1011 *

  • повторяющийся код в подклассах?
  • настройка какого-то счетного массива с ключом по имени класса в суперклассе?

Ответы [ 2 ]

3 голосов
/ 28 мая 2020

Вы можете хранить массив счетчиков в родительском классе, а не только одно целое число, индексированное с помощью static:class. Это будет ссылаться на имя класса текущего экземпляра, в отличие от self::, которое всегда ссылается на класс, в котором он используется.

class Vehicle
{
  private static $counts = [];

  public static function getCount()
  {
      return self::$counts[static::class];
  }

  public function __construct()
  {
      // Using a reference here to avoid undefined-index notices
      $target =& self::$counts[static::class];
      $target++;
  }
}

class Bike extends Vehicle {}

new Bike;
var_dump(Bike::getCount());
// int(1)

Полная демонстрация здесь: https://3v4l.org/Qibd7

Я также согласен с комментарием @ u_mulder, что это немного необычный шаблон. Определение класса должно касаться только атрибутов одного экземпляра, а не хранить глобальное состояние. Поддержание коллекции экземпляров (даже в простом массиве PHP) означало бы, что вы могли подсчитывать их независимо. Но решать вам.

2 голосов
/ 28 мая 2020

Многое зависит от того, где вы определяете счетчик и как вы к нему обращаетесь. Если у вас есть 1 счетчик в базовом классе, то есть только 1 счетчик. Если у вас есть счетчик в каждом классе, вам нужно знать, как получить доступ к правильному значению. Использование self или static обсуждается подробнее В чем разница между self :: $ bar и stati c :: $ bar в PHP?

class Vehicle
{
    protected static $_count=0;

    public static function getCount() {
        return static::$_count;
    }

    public function __construct($type, $year)
    {
        // Access the count in the current class (Bike or Car).
        static::$_count++;
        // Access the count in this class
        self::$_count++;
    }
}

class Bike extends Vehicle
{
    protected static $_count=0;
}

class Car extends Vehicle
{
    protected static $_count=0;
}

У этого есть оба, и в конструкторе он увеличивает их оба. Это означает, что имеется общее количество всех транспортных средств и каждого типа ...

echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;
$a = new Car("a", 1);
echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;
$a = new Bike("a", 1);
echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;

дает (хотя не очень ясно) ...

Vehicle::getCount()=0
Car::getCount()=0
Bike::getCount()=0
Vehicle::getCount()=1
Car::getCount()=1
Bike::getCount()=0
Vehicle::getCount()=2
Car::getCount()=1
Bike::getCount()=1
...