language/oop5/inheritance.xml
99744a3bfa1e5c09f75e7ee02a12c92f9e4ef438
...
...
@@ -32,6 +32,9 @@
32
32
<literal>protected</literal> method can be marked as
33
33
<literal>public</literal>, but they cannot be restricted, e.g.
34
34
marking a <literal>public</literal> property as <literal>private</literal>.
35
+
An exception are constructors, whose visibility can be restricted, e.g.
36
+
a <literal>public</literal> constructor can be marked as <literal>private</literal>
37
+
in a child class.
35
38
</para>
36
39

37
40
<note>
...
...
@@ -105,6 +108,81 @@ $bar->printPHP(); // Output: 'PHP is great'
105
108
</example>
106
109
</sect2>
107
110

111
+
<sect2 xml:id="language.oop5.inheritance.internal-classes">
112
+
<title>Return Type Compatibility with Internal Classes</title>
113
+
114
+
<para>
115
+
Prior to PHP 8.1, most internal classes or methods didn't declare their return types,
116
+
and any return type was allowed when extending them.
117
+
</para>
118
+
119
+
<para>
120
+
As of PHP 8.1.0, most internal methods started to "tentatively" declare their return type,
121
+
in that case the return type of methods should be compatible with the parent being extended;
122
+
otherwise, a deprecation notice is emitted.
123
+
Note that lack of an explicit return declaration is also considered a signature mismatch,
124
+
and thus results in the deprecation notice.
125
+
</para>
126
+
127
+
<para>
128
+
If the return type cannot be declared for an overriding method due to PHP cross-version compatibility concerns,
129
+
a <classname>ReturnTypeWillChange</classname> attribute can be added to silence the deprecation notice.
130
+
</para>
131
+
132
+
<example>
133
+
<title>The overriding method does not declare any return type</title>
134
+
<programlisting role="php">
135
+
<![CDATA[
136
+
<?php
137
+
class MyDateTime extends DateTime
138
+
{
139
+
public function modify(string $modifier) { return false; }
140
+
}
141
+
142
+
// "Deprecated: Return type of MyDateTime::modify(string $modifier) should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice" as of PHP 8.1.0
143
+
?>
144
+
]]>
145
+
</programlisting>
146
+
</example>
147
+
148
+
<example>
149
+
<title>The overriding method declares a wrong return type</title>
150
+
<programlisting role="php">
151
+
<![CDATA[
152
+
<?php
153
+
class MyDateTime extends DateTime
154
+
{
155
+
public function modify(string $modifier): ?DateTime { return null; }
156
+
}
157
+
158
+
// "Deprecated: Return type of MyDateTime::modify(string $modifier): ?DateTime should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice" as of PHP 8.1.0
159
+
?>
160
+
]]>
161
+
</programlisting>
162
+
</example>
163
+
164
+
<example>
165
+
<title>The overriding method declares a wrong return type without a deprecation notice</title>
166
+
<programlisting role="php">
167
+
<![CDATA[
168
+
<?php
169
+
class MyDateTime extends DateTime
170
+
{
171
+
/**
172
+
* @return DateTime|false
173
+
*/
174
+
#[\ReturnTypeWillChange]
175
+
public function modify(string $modifier) { return false; }
176
+
}
177
+
178
+
// No notice is triggered
179
+
?>
180
+
]]>
181
+
</programlisting>
182
+
</example>
183
+
184
+
</sect2>
185
+

108
186
</sect1>
109
187
110
188
<!-- Keep this comment at the end of the file
111
189