-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathinheritance.xml
220 lines (199 loc) · 7.05 KB
/
inheritance.xml
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: f94d903985119d3ac00f4528551df947f57b667f Maintainer: simp Status: ready -->
<sect1 xml:id="language.oop5.inheritance" xmlns="http://docbook.org/ns/docbook">
<title>Objekt-Vererbung</title>
<para>
Vererbung ist ein gängiges Prinzip der Programmierung und PHP verwendet
dieses Prinzip in seinem Objektmodell. Dieses Prinzip beeinflusst die
Art und Weise, in der mehrere Klassen und Objekte in Beziehung zueinander
stehen.
</para>
<para>
Wenn zum Beispiel eine Klasse erweitert wird, so erbt die Unterklasse
alle Methoden der Sichtbarkeiten public und protected sowie alle
Eigenschaften und Konstanten von der Elternklasse. Wenn eine Klasse diese
Methoden nicht überschreibt, wird die ursprüngliche Funktionalität
beibehalten.
</para>
<para>
Dies ist nützlich, um Funktionalität zu definieren und zu abstrahieren und
erlaubt es, zusätzliche Funktionalität in ähnlichen Objekten zu
implementieren, ohne sämtliche gemeinsame Funktionalitäten neu
implementieren zu müssen.
</para>
<para>
Private Methoden einer Elternklasse sind für eine Kindklasse nicht
zugänglich. Folglich können Kindklassen eine private Methode ohne
Berücksichtigung der normalen Vererbungsregeln selbst reimplementieren. Vor
PHP 8.0.0 wurden jedoch die Einschränkungen <literal>final</literal> und
<literal>static</literal> auf private Methoden angewandt. Ab PHP 8.0.0 ist
die einzige Einschränkung für private Methoden, die erzwungen wird, die die
<literal>private final</literal> bei Konstruktoren, da dies ein üblicher
Weg ist, den Konstruktor zu "deaktivieren", wenn stattdessen statische
Fabrikmethoden (factory methods) verwendet werden.
</para>
<para>
Die <link linkend="language.oop5.visibility">Sichtbarkeit</link> von
Methoden, Eigenschaften und Konstanten kann gelockert werden, so kann &zb;
eine <literal>protected</literal> Methode als <literal>public</literal>
markiert werden, aber sie können nicht eingeschränkt werden, indem &zb;
eine <literal>public</literal> Eigenschaft als <literal>private</literal>
markiert wird. Eine Ausnahme sind Konstruktoren, deren Sichtbarkeit
eingeschränkt werden kann, &zb; kann ein <literal>public</literal>
Konstruktor in einer Kindklasse als <literal>private</literal> markiert
werden.
</para>
<note>
<para>
Wenn Autoloading nicht verwendet wird, so müssen die Klassen definiert werden,
bevor sie verwendet werden. Wenn eine Klasse eine andere erweitert, so muss die
Elternklasse vor der Kindklasse deklariert werden. Diese Regel gilt für Klassen,
die von anderen Klassen und Interfaces erben.
</para>
</note>
<note>
<para>
Es ist nicht erlaubt, eine schreib- und lesbare Eigenschaft mit einer
<link linkend="language.oop5.properties.readonly-properties">schreibgeschützten Eigenschaft</link>
zu überschreiben oder umgekehrt.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class A {
public int $prop;
}
class B extends A {
// Unzulässig: lesen-schreiben -> nur-lesen
public readonly int $prop;
}
?>
]]>
</programlisting>
</informalexample>
</para>
</note>
<example>
<title>Beispiel für Vererbung</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo
{
public function printItem($string)
{
echo 'Foo: ' . $string . PHP_EOL;
}
public function printPHP()
{
echo 'PHP ist großartig.' . PHP_EOL;
}
}
class Bar extends Foo
{
public function printItem($string)
{
echo 'Bar: ' . $string . PHP_EOL;
}
}
$foo = new Foo();
$bar = new Bar();
$foo->printItem('baz'); // Ausgabe: 'Foo: baz'
$foo->printPHP(); // Ausgabe: 'PHP ist großartig.'
$bar->printItem('baz'); // Ausgabe: 'Bar: baz'
$bar->printPHP(); // Ausgabe: 'PHP ist großartig.'
?>
]]>
</programlisting>
</example>
<sect2 xml:id="language.oop5.inheritance.internal-classes">
<title>Kompatibilität des Rückgabetyps bei internen Klassen</title>
<para>
Vor PHP 8.1 haben die meisten internen Klassen oder Methoden ihren
Rückgabetyp nicht deklariert und wenn sie erweitert wurden, war jeder
Rückgabetyp erlaubt.
</para>
<para>
Seit PHP 8.1.0 sind die meisten internen Methoden dazu übergegangen, den
Typ des Rückgabewertes "vorläufig" zu deklarieren. In diesem Fall muss der
Typ des Rückgabewerts einer Methode mit dem des erweiterten Elternteils
kompatibel sein, andernfalls wird ein Missbilligungs-Hinweis ausgegeben.
Es ist zu beachten, dass eine fehlende explizite Deklaration des
Rückgabetyps ebenfalls als Signaturfehler betrachtet wird, und daher zu
einer entsprechenden Meldung führt.
</para>
<para>
Wenn der Rückgabetyp für eine überschreibende Methode aufgrund von
Kompatibilitätsproblemen zwischen PHP-Versionen nicht deklariert werden
kann, kann das Attribut <classname>ReturnTypeWillChange</classname>
hinzugefügt werden, um den Missbilligungs-Hinweis zu unterdrücken.
</para>
<example>
<title>Die überschreibende Methode deklariert keinen Rückgabetyp</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>Die überschreibende Methode deklariert einen falschen Rückgabetyp</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>Die überschreibende Methode deklariert einen falschen Rückgabetyp ohne Missbilligungs-Hinweis</title>
<programlisting role="php">
<![CDATA[
<?php
class MyDateTime extends DateTime
{
/**
* @return DateTime|false
*/
#[\ReturnTypeWillChange]
public function modify(string $modifier) { return false; }
}
// Es wird kein Missbilligungs-Hinweis ausgelöst
?>
]]>
</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
-->