File: inheritance.xml

package info (click to toggle)
php-doc 20241205~git.dfcbb86%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 70,956 kB
  • sloc: xml: 968,269; php: 23,883; javascript: 671; sh: 177; makefile: 37
file content (205 lines) | stat: -rw-r--r-- 6,387 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
 <sect1 xml:id="language.oop5.inheritance" xmlns="http://docbook.org/ns/docbook">
  <title>Object Inheritance</title>
  <para>
   Inheritance is a well-established programming principle, and PHP makes use
   of this principle in its object model. This principle will affect the way
   many classes and objects relate to one another.
  </para>
  <para>
   For example, when extending a class, the subclass inherits all of the
   public and protected methods, properties and constants from the parent class.
   Unless a class overrides
   those methods, they will retain their original functionality.
  </para>
  <para>
   This is useful for defining and abstracting functionality, and permits the
   implementation of additional functionality in similar objects without the
   need to reimplement all of the shared functionality.
  </para>
  <para>
   Private methods of a parent class are not accessible to a child class. As a result,
   child classes may reimplement a private method themselves without regard for normal
   inheritance rules.  Prior to PHP 8.0.0, however, <literal>final</literal> and <literal>static</literal>
   restrictions were applied to private methods.  As of PHP 8.0.0, the only private method
   restriction that is enforced is <literal>private final</literal> constructors, as that
   is a common way to "disable" the constructor when using static factory methods instead.
  </para>
 <para>
  The <link linkend="language.oop5.visibility">visibility</link>
  of methods, properties and constants can be relaxed, e.g. a
  <literal>protected</literal> method can be marked as
  <literal>public</literal>, but they cannot be restricted, e.g.
  marking a <literal>public</literal> property as <literal>private</literal>.
  An exception are constructors, whose visibility can be restricted, e.g.
  a <literal>public</literal> constructor can be marked as <literal>private</literal>
  in a child class.
 </para>

  <note>
   <para>
    Unless autoloading is used, the classes must be defined before they are
    used. If a class extends another, then the parent class must be declared 
    before the child class structure. This rule applies to classes that inherit 
    other classes and interfaces.
   </para>
  </note>
  <note>
   <para>
    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.
    <informalexample>
     <programlisting role="php">
<![CDATA[
<?php

class A {
    public int $prop;
}
class B extends A {
    // Illegal: read-write -> readonly
    public readonly int $prop;
}
?>
]]>
     </programlisting>
    </informalexample>
   </para>
  </note>

 <example>
  <title>Inheritance Example</title>
  <programlisting role="php">
<![CDATA[
<?php

class Foo
{
    public function printItem($string)
    {
        echo 'Foo: ' . $string . PHP_EOL;
    }
    
    public function printPHP()
    {
        echo 'PHP is great.' . PHP_EOL;
    }
}

class Bar extends Foo
{
    public function printItem($string)
    {
        echo 'Bar: ' . $string . PHP_EOL;
    }
}

$foo = new Foo();
$bar = new Bar();
$foo->printItem('baz'); // Output: 'Foo: baz'
$foo->printPHP();       // Output: 'PHP is great' 
$bar->printItem('baz'); // Output: 'Bar: baz'
$bar->printPHP();       // Output: 'PHP is great'

?>
]]>
  </programlisting>
 </example>

  <sect2 xml:id="language.oop5.inheritance.internal-classes">
   <title>Return Type Compatibility with Internal Classes</title>
 
   <para>
    Prior to PHP 8.1, most internal classes or methods didn't declare their return types,
    and any return type was allowed when extending them.
   </para>
 
   <para>
    As of PHP 8.1.0, most internal methods started to "tentatively" declare their return type,
    in that case the return type of methods should be compatible with the parent being extended;
    otherwise, a deprecation notice is emitted.
    Note that lack of an explicit return declaration is also considered a signature mismatch,
    and thus results in the deprecation notice.
   </para>
 
   <para>
    If the return type cannot be declared for an overriding method due to PHP cross-version compatibility concerns,
    a <classname>ReturnTypeWillChange</classname> attribute can be added to silence the deprecation notice.
   </para>
 
   <example>
    <title>The overriding method does not declare any return type</title>
    <programlisting role="php">
<![CDATA[
<?php
class MyDateTime extends DateTime
{
    public function modify(string $modifier) { return false; }
}
 
// "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
?> 
]]>
    </programlisting>
   </example>
 
   <example>
    <title>The overriding method declares a wrong return type</title>
    <programlisting role="php">
<![CDATA[
<?php
class MyDateTime extends DateTime
{
    public function modify(string $modifier): ?DateTime { return null; }
}
 
// "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
?> 
]]>
    </programlisting>
   </example>
 
   <example>
    <title>The overriding method declares a wrong return type without a deprecation notice</title>
    <programlisting role="php">
<![CDATA[
<?php
class MyDateTime extends DateTime
{
    /**
     * @return DateTime|false
     */
    #[\ReturnTypeWillChange]
    public function modify(string $modifier) { return false; }
}
 
// No notice is triggered 
?> 
]]>
    </programlisting>
   </example>
 
  </sect2>

 </sect1>
 
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->