-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy pathoverloading.xml
More file actions
343 lines (295 loc) · 10.7 KB
/
overloading.xml
File metadata and controls
343 lines (295 loc) · 10.7 KB
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: d6f54016d62904cfd8200604aadd5e3f0d9bad97 Maintainer: simp Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.oop5.overloading" xmlns="http://docbook.org/ns/docbook">
<title>Überladung</title>
<para>
Überladung bietet in PHP Möglichkeiten, um dynamisch
Eigenschaften und Methoden zu <quote>erzeugen</quote>.
Diese dynamisch erzeugten Entitäten werden unter
Zuhilfenahme von magischen Methoden verarbeitet,
die man in einer Klasse zu verschiedenen Aktivitäten
definieren kann.
</para>
<para>
Die Überladungsmethoden werden aufgerufen, wenn mit
Eigenschaften oder Methoden interagiert wird, die entweder
nicht deklariert wurden oder im aktuellen Geltungsbereich
nicht <link linkend="language.oop5.visibility">sichtbar</link>
sind. Im Rest dieses Abschnitts werden die Begriffe
<quote>unzugreifbare Eigenschaft</quote> und
<quote>unzugreifbare Methode</quote> verwendet, um auf die
Kombination von Deklaration und Sichtbarkeit zu verweisen.
</para>
<para>
Alle Überladungsmethoden müssen als <literal>public</literal>
definiert sein.
</para>
<note>
<para>
Keiner der Parameter dieser magischen Methoden kann
<link linkend="functions.arguments.by-reference">als
Referenz</link> übergeben werden.
</para>
</note>
<note>
<para>
Die Interpretation von <quote>Überladung</quote> weicht
von den meisten objektorientierten Programmiersprachen
ab. Traditionell bezeichnet Überladung die Möglichkeit
mehrere Methoden mit gleichem Namen aber unterschiedlichen
Anzahlen und Typen von Parametern zu definieren.
</para>
</note>
<sect2 xml:id="language.oop5.overloading.members">
<title>Überladung von Eigenschaften</title>
<methodsynopsis xml:id="object.set">
<modifier>public</modifier> <type>void</type><methodname>__set</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam><type>mixed</type><parameter>value</parameter></methodparam>
</methodsynopsis>
<methodsynopsis xml:id="object.get">
<modifier>public</modifier> <type>mixed</type><methodname>__get</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
</methodsynopsis>
<methodsynopsis xml:id="object.isset">
<modifier>public</modifier> <type>bool</type><methodname>__isset</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
</methodsynopsis>
<methodsynopsis xml:id="object.unset">
<modifier>public</modifier> <type>void</type><methodname>__unset</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
</methodsynopsis>
<para>
<link linkend="object.set">__set</link> wird aufgerufen, wenn Daten in
unzugreifbare (protected oder private) Eigenschaften geschrieben werden
sollen.
</para>
<para>
<link linkend="object.get">__get</link> wird verwendet, um Daten aus
unzugreifbaren (protected oder private) Eigenschaften zu lesen.
</para>
<para>
<link linkend="object.isset">__isset</link> wird aufgerufen, indem
<function>isset</function> oder <function>empty</function>
auf unzugreifbare (protected oder private) Eigenschaften angewendet wird.
</para>
<para>
<link linkend="object.unset">__unset</link> wird aufgerufen, wenn
<function>unset</function> für unzugreifbaren (protected oder private)
Eigenschaften aufgerufen wird.
</para>
<para>
Der Parameter <varname>$name</varname> beinhaltet den Namen
der Eigenschaft, mit der interagiert wird. Der Parameter
<varname>$value</varname> der Funktion <link linkend="object.set">__set</link>
spezifiziert den Wert den die Eigenschaft <varname>$name</varname>
annehmen soll.
</para>
<para>
Überladung von Eigenschaften funktioniert nur im Kontext von
Objekten. Diese magischen Methoden werden nicht aus einem
statischen Kontext aufgerufen. Diese Methoden sollten daher
nicht als <link linkend="language.oop5.static">static</link>
deklariert werden. Eine Warnung wird ausgegeben,
wenn eine dieser magischen Überladungsmethoden als
<literal>static</literal> deklariert ist.
</para>
<note>
<para>
Der Rückgabewert von <link linkend="object.set">__set</link> wird, aufgrund
der Behandlung des Zuweisungsoperators in PHP, ignoriert.
Aus ähnlichen Gründen wird <link linkend="object.get">__get</link> nicht
aufgerufen, wenn man Zuweisungen in etwa wie folgt verkettet:
<literal><![CDATA[ $a = $obj->b = 8; ]]></literal>
</para>
</note>
<note>
<para>
PHP ruft niemals eine überladene Methode von derselben überladenen
Methode aus auf. Das bedeutet zum Beispiel, dass
<code>return $this->foo</code> innerhalb von
<link linkend="object.get">__get()</link> &null; zurückgibt und ein
<constant>E_WARNING</constant> auslöst, wenn die Eigenschaft
<literal>foo</literal> nicht definiert ist, anstatt
<link linkend="object.get">__get()</link> ein zweites Mal aufzurufen. Es
ist jedoch möglich, dass eine überladene Methode implizit eine andere
überladene Methode aufruft (&zb; löst
<link linkend="object.set">__set()</link> den Aufruf von
<link linkend="object.get">__get()</link> aus).
</para>
</note>
<example>
<title>
Überladung von Eigenschaften mit den Methoden
<link linkend="object.get">__get</link>, <link linkend="object.set">__set</link>,
<link linkend="object.isset">__isset</link> und <link linkend="object.unset">__unset</link>
</title>
<programlisting role="php">
<![CDATA[
<?php
class EigenschaftTest
{
/** Speicherplatz für überladene Daten. */
private $data = array();
/** Überladung wird nicht bei deklarierten Eigenschaften benutzt. */
public $declared = 1;
/** Überladung wird nur von außerhalb der Klasse angewendet. */
private $hidden = 2;
public function __set($name, $value)
{
echo "Setze '$name' auf '$value'\n";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Lese '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefinierte Eigenschaft für __get(): ' . $name .
' in ' . $trace[0]['file'] .
' Zeile ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
public function __isset($name)
{
echo "Ist '$name' gesetzt?\n";
return isset($this->data[$name]);
}
public function __unset($name)
{
echo "Lösche '$name'\n";
unset($this->data[$name]);
}
/** Keine magische Methode, nur beispielhaft hier. */
public function getHidden()
{
return $this->hidden;
}
}
$obj = new EigenschaftTest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "Wir experimentieren nun mit der private-Eigenschaft 'hidden':\n";
echo "Private ist innerhalb der Klasse sichtbar, also wird __get() nicht benutzt...\n";
echo $obj->getHidden() . "\n";
echo "Private nicht sichtbar von außerhalb der Klasse, also wird __get() benutzt...\n";
echo $obj->hidden . "\n";
?>
]]>
</programlisting>
&example.outputs;
<screen role="php">
<![CDATA[
Setze 'a' auf '1'
Lese 'a'
1
Ist 'a' gesetzt?
bool(true)
Lösche 'a'
Ist 'a' gesetzt?
bool(false)
1
Wir experimentieren nun mit der private-Eigenschaft 'hidden':
Private ist innerhalb der Klasse sichtbar, also wird __get() nicht benutzt...
2
Private nicht sichtbar von außerhalb der Klasse, also wird __get() benutzt...
Lese 'hidden'
Notice: Undefinierte Eigenschaft für __get(): hidden in <file> Zeile 70 in <file> on line 29
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.overloading.methods">
<title>Überladung von Methoden</title>
<methodsynopsis xml:id="object.call">
<modifier>public</modifier> <type>mixed</type><methodname>__call</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam><type>array</type><parameter>arguments</parameter></methodparam>
</methodsynopsis>
<methodsynopsis xml:id="object.callstatic">
<modifier>public static</modifier> <type>mixed</type><methodname>__callStatic</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam><type>array</type><parameter>arguments</parameter></methodparam>
</methodsynopsis>
<para>
<link linkend="object.call">__call</link> wird aufgerufen, wenn eine unzugreifbare
Methode in einem Objekt aufgerufen wird.
</para>
<para>
<link linkend="object.callstatic">__callStatic</link> wird aufgerufen, wenn eine
unzugreifbare Methode in einem statischen Kontext aufgerufen wird.
</para>
<para>
Der Parameter <varname>$name</varname> ist der Name der aufgerufenen
Methode. Der Parameter <varname>$arguments</varname> beinhaltet ein
Array mit den Parametern, die der Methode <varname>$name</varname>
übergeben wurden.
</para>
<example>
<title>
Überladung von Methoden mit den methoden <link linkend="object.call">__call</link>
und <link linkend="object.callstatic">__callStatic</link>
</title>
<programlisting role="php">
<![CDATA[
<?php
class MethodenTest {
public function __call($name, $arguments)
{
// Achtung: Der Wert von $name beachtet die Groß-/Kleinschreibung
echo "Rufe die Objektmethode '$name' "
. implode(', ', $arguments). "\n";
}
public static function __callStatic($name, $arguments)
{
// Achtung: Der Wert von $name beachtet die Groß-/Kleinschreibung
echo "Rufe die statische Methode '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodenTest;
$obj->runTest('eines Objektes auf');
MethodenTest::runTest('aus statischem Kontext auf');
?>
]]>
</programlisting>
&example.outputs;
<screen role="php">
<![CDATA[
Rufe die Objektmethode 'runTest' eines Objektes auf
Rufe die statische Methode 'runTest' aus statischem Kontext auf
]]>
</screen>
</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
-->