Конечные и Readonly классы в PHP

RedDeveloper
23.03.2023 11:48
Конечные и Readonly классы в PHP

конечные классы

В прошлом, когда вы не хотели, чтобы другие классы расширяли определенный класс, вы могли пометить его как final.

Рассмотрим приведенный ниже код:

<?php

namespace App\Utils;

class ParentClass
{
    public function __construct(protected string $name) {
    }
}
<?php

namespace App\Utils;

class ChildClass extends ParentClass
{
}

Итак, у нас есть 2 класса. AParentClass и ChildClass, который расширяет родительский класс.

Мы можем использовать ChildClass следующим образом:

<?php

use App\Utils\ChildClass;

$obj = new ChildClass('Antonio');

var_dump($obj);

И это выведет публичные свойства ChildClass, а также унаследованные свойства от ParentClass следующим образом:

И это выведет публичные свойства ChildClass а также унаследованные свойства от

Теперь, если мы не хотим, чтобы наш класс был расширен, мы просто ставим слово final в начале класса, как показано ниже:

<?php

namespace App\Utils;

final class ParentClass
{
    public function __construct(
        protected string $name
    ) {
    }
}

И вызов $obj = new ChildClass('Antonio'); снова приведет к тому, что: Класс App\Utils\ChildClass не может расширять финальный класс App\Utils\ParentClass.

Итак, определение final в PHP следующее:

Ключевое слово final используется для предотвращения наследования класса и для предотвращения переопределения унаследованного метода.
  1. Поэтому если мы объявляем метод класса как final, то этот метод не может быть переопределен дочерним классом.
  2. То же самое и с методом, если мы объявляем класс как final, то этот класс больше не может быть расширен.

класс readonly

Классы readonly добавлены в PHP 8.2 .

Final и readonlyare - два совершенно разных понятия в PHP и имеют разные последствия, когда применяются к классу.

Как мы видели ранее, сделать класс конечным означает, что он не может быть расширен.

final class ParentClass{}

class ChildClass extends ParentClass{}

// Fatal error: Class ChildClass cannot extend final class ParentClass

С другой стороны, сделать класс доступным для чтения означает несколько вещей:

  1. Все свойства экземпляра класса неявно помечаются как readonly и не могут быть переназначены.
  2. Создание динамических свойств не допускается.
  3. Только класс readonly может расширять другой класс readonly.
  4. Свойства readonly могут быть переопределены.

Например:

// PHP 8.2+
readonly class ParentClass
{
    public function __construct(
        public string $name
    ) {}
}

$obj = new ParentClass('Antonio');
echo 'Hello, My name is ' . $obj ->name; // "Hello, My name is Antonio"

Если вы попытаетесь повторно присвоить значение любому свойству объекта после инстанцирования, это приведет к следующей ошибке:

// PHP 8.2+
$obj ->name = 'Ndershkuesi';

// Fatal error: Uncaught Error: Cannot modify readonly property ParentClass::$name

Это происходит потому, что все свойства неявно становятся readonly, когда вы помечаете класс как readonly.

ПРИМЕЧАНИЕ: свойство readonly не может иметь значение по умолчанию.

final и readonly

Вы также можете пометить класс как readonly и final, это означает:

  1. Все свойства класса неявно являются readonly.
  2. Класс не может быть расширен.

Пример:

// PHP 8.2+
final readonly class ParentClass {
    public function __construct(
        public string $name
    ) {}
}

Использование:

$obj = new ParentClass('Antonio');
echo 'My name is ' . $obj->name; // "My name is Antonio"

И если вы попытаетесь присвоить значение любому свойству объекта или попытаетесь расширить класс, то он выдаст ошибку следующим образом:

// PHP 8.2+

$obj->name = 'Ndershkuesi';
// Fatal error: Uncaught Error: Cannot modify readonly property ParentClass::$name

readonly class ChildClass extends ParentClass {}
// Fatal error: Class ChildClass cannot extend final class Shape

Не стесняйтесь Подписаться на большее количество подобных материалов 🔔, хлопать 👏🏻 , комментировать 💬 и делиться статьей со всеми желающими.

И как это было всегда, я ценю вашу поддержку, и спасибо, что читаете.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?

20.08.2023 18:21

Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией

20.08.2023 17:46

В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox

19.08.2023 18:39

Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest

19.08.2023 17:22

В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!

Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️

18.08.2023 20:33

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL

14.08.2023 14:49

Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.