language/oop5/inheritance.xml
f94d903985119d3ac00f4528551df947f57b667f
...
...
@@ -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>
...
...
@@ -42,14 +45,34 @@
42
45
other classes and interfaces.
43
46
</para>
44
47
</note>
45
-

46
-
<sect2 xml:id="language.oop5.inheritance.examples">
47
-
<example xml:id="language.oop5.inheritance.examples.ex1">
48
-
<title>Inheritance Example</title>
48
+
<note>
49
+
<para>
50
+
It is not allowed to override a read-write property with a <link linkend="language.oop5.properties.readonly-properties">readonly property</link> or vice versa.
51
+
<informalexample>
49
52
<programlisting role="php">
50
53
<![CDATA[
51
54
<?php
52
55

56
+
class A {
57
+
public int $prop;
58
+
}
59
+
class B extends A {
60
+
// Illegal: read-write -> readonly
61
+
public readonly int $prop;
62
+
}
63
+
?>
64
+
]]>
65
+
</programlisting>
66
+
</informalexample>
67
+
</para>
68
+
</note>
69
+

70
+
<example>
71
+
<title>Inheritance Example</title>
72
+
<programlisting role="php">
73
+
<![CDATA[
74
+
<?php
75
+

53
76
class Foo
54
77
{
55
78
public function printItem($string)
...
...
@@ -80,8 +103,82 @@ $bar->printPHP(); // Output: 'PHP is great'
80
103

81
104
?>
82
105
]]>
106
+
</programlisting>
107
+
</example>
108
+

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

87
184
</sect1>
88
185