language/oop5/inheritance.xml
f94d903985119d3ac00f4528551df947f57b667f
...
...
@@ -8,8 +8,9 @@
8
8
many classes and objects relate to one another.
9
9
</para>
10
10
<para>
11
-
For example, when you extend a class, the subclass inherits all of the
12
-
public and protected methods from the parent class. Unless a class overrides
11
+
For example, when extending a class, the subclass inherits all of the
12
+
public and protected methods, properties and constants from the parent class.
13
+
Unless a class overrides
13
14
those methods, they will retain their original functionality.
14
15
</para>
15
16
<para>
...
...
@@ -17,23 +18,61 @@
17
18
implementation of additional functionality in similar objects without the
18
19
need to reimplement all of the shared functionality.
19
20
</para>
21
+
<para>
22
+
Private methods of a parent class are not accessible to a child class. As a result,
23
+
child classes may reimplement a private method themselves without regard for normal
24
+
inheritance rules. Prior to PHP 8.0.0, however, <literal>final</literal> and <literal>static</literal>
25
+
restrictions were applied to private methods. As of PHP 8.0.0, the only private method
26
+
restriction that is enforced is <literal>private final</literal> constructors, as that
27
+
is a common way to "disable" the constructor when using static factory methods instead.
28
+
</para>
29
+
<para>
30
+
The <link linkend="language.oop5.visibility">visibility</link>
31
+
of methods, properties and constants can be relaxed, e.g. a
32
+
<literal>protected</literal> method can be marked as
33
+
<literal>public</literal>, but they cannot be restricted, e.g.
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.
38
+
</para>
20
39

21
40
<note>
22
41
<para>
23
-
Unless autoloading is used, then classes must be defined before they are
42
+
Unless autoloading is used, the classes must be defined before they are
24
43
used. If a class extends another, then the parent class must be declared
25
44
before the child class structure. This rule applies to classes that inherit
26
45
other classes and interfaces.
27
46
</para>
28
47
</note>
29
-

30
-
<sect2 xml:id="language.oop5.inheritance.examples">
31
-
<example xml:id="language.oop5.inheritance.examples.ex1">
32
-
<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>
33
52
<programlisting role="php">
34
53
<![CDATA[
35
54
<?php
36
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
+

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

65
104
?>
66
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
+
]]>
67
143
</programlisting>
68
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
+
]]>
159
+
</programlisting>
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
+
69
182
</sect2>
70
183

71
184
</sect1>
72
185