Статья

📘 Глава 21. Статические свойства и методы, `self`, `static`, абстрактные и финальные классы

📌 Статические свойства и методы

Иногда удобно обращаться к свойствам или методам класса без создания его экземпляра. Для этого используются статические (static) члены класса.


🧪 Пример статического метода

class MathHelper {
    public static function square(int $x): int {
        return $x * $x;
    }
}

echo MathHelper::square(5); // 25
  • Метод square можно вызывать без new MathHelper()

  • Полезно для утилит, хелперов, констант и фабрик


🗃 Пример статического свойства

class Config {
    public static string $appName = "MyApp";
}

echo Config::$appName; // MyApp

🔄 Отличие self и static

class Base {
    public static function who() {
        echo __CLASS__;
    }

    public static function test() {
        static::who();
    }
}

class Child extends Base {
    public static function who() {
        echo __CLASS__;
    }
}

Child::test(); // Child (а не Base!)
  • self:: — жёсткая ссылка на текущий класс, где объявлен метод

  • static:: — позднее статическое связывание (late static binding), позволяет учитывать наследование


🧱 Абстрактные классы

Абстрактный класс — это шаблон, который не может быть создан напрямую. В нём могут быть как реализованные, так и абстрактные (незаконченные) методы.


✏️ Пример

abstract class Shape {
    abstract public function area(): float;

    public function say() {
        echo "I'm a shape!";
    }
}

class Square extends Shape {
    public function __construct(private float $side) {}

    public function area(): float {
        return $this->side * $this->side;
    }
}
  • Метод area обязателен для реализации в наследнике

  • Можно использовать абстрактные классы как универсальный интерфейс + частичная реализация


🔒 Финальные классы и методы

🚫 final class

final class Core {
    // ...
}
  • Нельзя унаследовать Core

🚫 final function

class A {
    final public function log() {
        echo "Logging...";
    }
}

class B extends A {
    // public function log() {} ❌ Ошибка!
}
  • Метод log нельзя переопределить в потомках

🧰 Где использовать?

  • static — утилиты, глобальные флаги, конфиги, фабрики, кеш

  • self:: — если точно знаешь, что метод/свойство из текущего класса

  • static:: — когда хочешь использовать динамическое поведение в наследниках

  • abstract — для создания универсальных основ

  • final — защита от нежелательного наследования и переопределения


💡 Пример: простой регистратор логов

class Logger {
    protected static array $logs = [];

    public static function log(string $msg): void {
        self::$logs[] = $msg;
    }

    public static function all(): array {
        return self::$logs;
    }
}

Logger::log("Started app");
Logger::log("DB connected");

print_r(Logger::all());

✅ Что ты усвоил:

  • Как и зачем использовать static, self, static::

  • Что такое абстрактные и финальные классы

  • Принципы построения удобных и безопасных архитектур


⏭ В следующей главе:

Перейдём к интерфейсам, множественному программному контракту, dependency injection, и SOLID-принципам — это фундамент чистого и масштабируемого кода.

PHP
Для ответа вы можете авторизоваться