11<?xml version =" 1.0" encoding =" utf-8" ?>
2- <!-- EN-Revision: f5e5b54129045a7d02c5285a88cea0abff8ffb6f Maintainer: irker Status: ready -->
2+ <!-- EN-Revision: 7d7b378abd302430b8ce7cedb4b78c7033f5e88c Maintainer: irker Status: ready -->
33<!-- Reviewed: no -->
44<sect1 xml : id =" language.oop5.visibility" xmlns =" http://docbook.org/ns/docbook" >
55 <title >Область видимости</title >
2020 Свойства, объявленные без явного ключевого слова области видимости,
2121 определяются как общедоступные (public).
2222 </para >
23- <para >
24- <example >
23+ <example >
2524 <title >Объявление свойства класса</title >
2625 <programlisting role =" php" >
2726<![CDATA[
@@ -77,7 +76,120 @@ $obj2->printHello(); // Выводит Public2, Protected2, Undefined
7776]]>
7877 </programlisting >
7978 </example >
80- </para >
79+ <sect3 xml : id =" language.oop5.visibility-members-aviz" >
80+ <title >Асимметричная область видимости свойств</title >
81+ <simpara >
82+ Начиная с PHP 8.4, свойства также могут иметь асимметричную область видимости
83+ для чтения (<literal >get</literal >) и записи (<literal >set</literal >).
84+ В частности, область видимости <literal >set</literal > может быть задана отдельно,
85+ при условии, что она такая же или менее строгая, чем область видимости по умолчанию.
86+ </simpara >
87+ <example >
88+ <title >Асимметричная область видимости свойств</title >
89+ <programlisting role =" php" >
90+ <![CDATA[
91+ <?php
92+ class Book
93+ {
94+ public function __construct(
95+ public private(set) string $title,
96+ public protected(set) string $author,
97+ protected private(set) int $pubYear,
98+ ) {}
99+ }
100+
101+ class SpecialBook extends Book
102+ {
103+ public function update(string $author, int $year): void
104+ {
105+ $this->author = $author; // Всё хорошо
106+ $this->pubYear = $year; // Критическая ошибка
107+ }
108+ }
109+
110+ $b = new Book('How to PHP', 'Peter H. Peterson', 2024);
111+
112+ echo $b->title; // Всё хорошо
113+ echo $b->author; // Всё хорошо
114+ echo $b->pubYear; // Критическая ошибка
115+
116+ $b->title = 'How not to PHP'; // Критическая ошибка
117+ $b->author = 'Pedro H. Peterson'; // Критическая ошибка
118+ $b->pubYear = 2023; // Критическая ошибка
119+ ?>
120+ ]]>
121+ </programlisting >
122+ </example >
123+ <para >Есть несколько предостережений относительно асимметричной области видимости:</para >
124+ <itemizedlist >
125+ <listitem >
126+ <simpara >
127+ Отдельная область видимость <literal >set</literal > может быть только у типизированных свойств.
128+ </simpara >
129+ </listitem >
130+ <listitem >
131+ <simpara >
132+ Область видимости <literal >set</literal > должна быть такой же, как и <literal >get</literal > или более строгой.
133+ То есть <code >public protected(set)</code > и <code >protected protected(set)</code > допустимы,
134+ но <code >protected public(set)</code > приведёт к синтаксической ошибке.
135+ </simpara >
136+ </listitem >
137+ <listitem >
138+ <simpara >
139+ Если свойство <literal >public</literal >, то основная область видимости может быть опущена.
140+ То есть <code >public private(set)</code > и <code >private(set)</code > приведут к одному и тому же результату.
141+ </simpara >
142+ </listitem >
143+ <listitem >
144+ <simpara >
145+ Свойство с областью видимости <literal >private(set)</literal > автоматически становится окончательным (<literal >final</literal >)
146+ и не может быть повторно объявлено в дочернем классе.
147+ </simpara >
148+ </listitem >
149+ <listitem >
150+ <simpara >
151+ Получение ссылки на свойство соответствует видимости <literal >set</literal >, а не <literal >get</literal >.
152+ Это связано с тем, что ссылка может быть использована для изменения значения свойства.
153+ </simpara >
154+ </listitem >
155+ <listitem >
156+ <simpara >
157+ Аналогично, попытка записи в свойство массива включает в себя как операцию <literal >get</literal >,
158+ так и <literal >set</literal >, и поэтому будет следовать области видимости <literal >set</literal >,
159+ поскольку она всегда является более строгой.
160+ </simpara >
161+ </listitem >
162+ </itemizedlist >
163+ <simpara >
164+ При наследовании класса, дочерний класс может переопределить любое свойство, которое не является окончательным (<literal >final</literal >).
165+ При этом он может наследовать либо основную видимость, либо видимость <literal >set</literal >, при условии,
166+ что новая видимость будет такой же или менее строгой, чем у родительского класса.
167+ Однако имейте в виду, что если переопределяется свойство <literal >private</literal >, оно не изменяет родительское свойство,
168+ а создаёт новое свойство с другим внутренним именем.
169+ </simpara >
170+ <example >
171+ <title >Наследование свойств с асимметричной областью видимости</title >
172+ <programlisting role =" php" >
173+ <![CDATA[
174+ <?php
175+ class Book
176+ {
177+ protected string $title;
178+ public protected(set) string $author;
179+ protected private(set) int $pubYear;
180+ }
181+
182+ class SpecialBook extends Book
183+ {
184+ public protected(set) $title; // Всё хорошо, так как чтение менее строгое, а запись – такая же.
185+ public string $author; // Всё хорошо, так как чтение такое же, а запись – менее строгая.
186+ public protected(set) int $pubYear; // Критическая ошибка. Свойства private(set) являются окончательными.
187+ }
188+ ?>
189+ ]]>
190+ </programlisting >
191+ </example >
192+ </sect3 >
81193 </sect2 >
82194
83195 <sect2 xml : id =" language.oop5.visiblity-methods" >
@@ -86,8 +198,7 @@ $obj2->printHello(); // Выводит Public2, Protected2, Undefined
86198 Методы класса могут быть определены как public, private или protected.
87199 Методы, объявленные без указания области видимости, определяются как public.
88200 </para >
89- <para >
90- <example >
201+ <example >
91202 <title >Объявление метода</title >
92203 <programlisting role =" php" >
93204<![CDATA[
@@ -176,8 +287,7 @@ $myFoo->test(); // Bar::testPrivate
176287?>
177288]]>
178289 </programlisting >
179- </example >
180- </para >
290+ </example >
181291 </sect2 >
182292
183293 <sect2 xml : id =" language.oop5.visiblity-constants" >
@@ -187,8 +297,7 @@ $myFoo->test(); // Bar::testPrivate
187297 protected. Константы, объявленные без указания области видимости,
188298 определяются как public.
189299 </para >
190- <para >
191- <example >
300+ <example >
192301 <title >Объявление констант, начиная с PHP 7.1.0</title >
193302 <programlisting role =" php" >
194303<![CDATA[
@@ -243,7 +352,6 @@ $myclass2->foo2(); // Выводятся константы public и protected,
243352]]>
244353 </programlisting >
245354 </example >
246- </para >
247355 </sect2 >
248356
249357 <sect2 xml : id =" language.oop5.visibility-other-objects" >
0 commit comments