Skip to content

Commit 6b509cc

Browse files
authored
Fold comments into interfaces page
Co-authored-by: Kamil Tekiela <[email protected]> Closes GH-594.
1 parent 184f3f7 commit 6b509cc

File tree

1 file changed

+121
-29
lines changed

1 file changed

+121
-29
lines changed

language/oop5/interfaces.xml

Lines changed: 121 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
<para>
66
Object interfaces allow you to create code which specifies which methods a
77
class must implement, without having to define how these methods are
8-
implemented.
8+
implemented. Interfaces share a namespace with classes and traits, so they may
9+
not use the same name.
910
</para>
1011
<para>
1112
Interfaces are defined in the same way as a class, but with the <literal>interface</literal>
@@ -16,14 +17,34 @@
1617
All methods declared in an interface must be public; this is the nature of an
1718
interface.
1819
</para>
19-
20+
<para>
21+
In practice, interfaces serve two complementary purposes:
22+
</para>
23+
<simplelist>
24+
<member>
25+
To allow developers to create objects of different classes that may be used interchangeably
26+
because they implement the same interface or interfaces. A common example is multiple database access services,
27+
multiple payment gateways, or different caching strategies. Different implementations may
28+
be swapped out without requiring any changes to the code that uses them.
29+
</member>
30+
<member>
31+
To allow a function or method to accept and operate on a parameter that conforms to an
32+
interface, while not caring what else the object may do or how it is implemented. These interfaces
33+
are often named like <literal>Iterable</literal>, <literal>Cacheable</literal>, <literal>Renderable</literal>,
34+
or so on to describe the significance of the behavior.
35+
</member>
36+
</simplelist>
37+
<para>
38+
Interfaces may define
39+
<link linkend="language.oop5.magic">magic methods</link> to require implementing classes to
40+
implement those methods.
41+
</para>
2042
<note>
2143
<para>
22-
It is possible to declare
23-
<link linkend="language.oop5.magic">magic methods</link> such as the
24-
<link linkend="language.oop5.decon.constructor">constructor</link>
25-
in an interface, which can be useful in some contexts,
26-
e.g. for use by factories.
44+
Although they are supported, including <link linkend="language.oop5.decon.constructor">constructors</link>
45+
in interfaces is strongly discouraged. Doing so significantly reduces the flexibility of the object implementing the
46+
interface. Additionally, constructors are not enforced by inheritance rules, which can cause inconsistent
47+
and unexpected behavior.
2748
</para>
2849
</note>
2950

@@ -41,6 +62,14 @@
4162
same name, only if the method declaration in both interfaces is identical.
4263
</para>
4364
</warning>
65+
<warning>
66+
<para>
67+
A class that implements an interface may use a different name for its parameters than
68+
the interface. However, as of PHP 8.0 the language supports named arguments, which means
69+
callers may rely on the parameter name in the interface. For that reason, it is strongly
70+
recommended that developers use the same parameter names as the interface being implemented.
71+
</para>
72+
</warning>
4473
<note>
4574
<para>
4675
Interfaces can be extended like classes using the <link linkend="language.oop5.inheritance">extends</link>
@@ -49,8 +78,8 @@
4978
</note>
5079
<note>
5180
<para>
52-
The class implementing the interface must declare a method which has a
53-
<link linkend="language.oop.lsp">compatible signature</link>.
81+
The class implementing the interface must declare all methods in the interface
82+
with a <link linkend="language.oop.lsp">compatible signature</link>.
5483
</para>
5584
</note>
5685
</sect2>
@@ -71,18 +100,18 @@
71100
<![CDATA[
72101
<?php
73102
74-
// Declare the interface 'iTemplate'
75-
interface iTemplate
103+
// Declare the interface 'Template'
104+
interface Template
76105
{
77106
public function setVariable($name, $var);
78107
public function getHtml($template);
79108
}
80109
81110
// Implement the interface
82111
// This will work
83-
class Template implements iTemplate
112+
class WorkingTemplate implements Template
84113
{
85-
private $vars = array();
114+
private $vars = [];
86115
87116
public function setVariable($name, $var)
88117
{
@@ -101,10 +130,10 @@ class Template implements iTemplate
101130
102131
// This will not work
103132
// Fatal error: Class BadTemplate contains 1 abstract methods
104-
// and must therefore be declared abstract (iTemplate::getHtml)
105-
class BadTemplate implements iTemplate
133+
// and must therefore be declared abstract (Template::getHtml)
134+
class BadTemplate implements Template
106135
{
107-
private $vars = array();
136+
private $vars = [];
108137
109138
public function setVariable($name, $var)
110139
{
@@ -120,18 +149,18 @@ class BadTemplate implements iTemplate
120149
<programlisting role="php">
121150
<![CDATA[
122151
<?php
123-
interface a
152+
interface A
124153
{
125154
public function foo();
126155
}
127156
128-
interface b extends a
157+
interface B extends A
129158
{
130159
public function baz(Baz $baz);
131160
}
132161
133162
// This will work
134-
class c implements b
163+
class C implements B
135164
{
136165
public function foo()
137166
{
@@ -143,7 +172,7 @@ class c implements b
143172
}
144173
145174
// This will not work and result in a fatal error
146-
class d implements b
175+
class D implements B
147176
{
148177
public function foo()
149178
{
@@ -162,22 +191,22 @@ class d implements b
162191
<programlisting role="php">
163192
<![CDATA[
164193
<?php
165-
interface a
194+
interface A
166195
{
167196
public function foo();
168197
}
169198
170-
interface b
199+
interface B
171200
{
172201
public function bar();
173202
}
174203
175-
interface c extends a, b
204+
interface C extends A, B
176205
{
177206
public function baz();
178207
}
179208
180-
class d implements c
209+
class D implements C
181210
{
182211
public function foo()
183212
{
@@ -200,20 +229,83 @@ class d implements c
200229
<programlisting role="php">
201230
<![CDATA[
202231
<?php
203-
interface a
232+
interface A
204233
{
205-
const b = 'Interface constant';
234+
const B = 'Interface constant';
206235
}
207236
208237
// Prints: Interface constant
209-
echo a::b;
238+
echo A::B;
210239
211240
212241
// This will however not work because it's not allowed to
213242
// override constants.
214-
class b implements a
243+
class B implements A
244+
{
245+
const B = 'Class constant';
246+
}
247+
?>
248+
]]>
249+
</programlisting>
250+
</example>
251+
<example xml:id="language.oop5.interfaces.examples.ex5">
252+
<title>Interfaces with abstract classes</title>
253+
<programlisting role="php">
254+
<![CDATA[
255+
<?php
256+
interface A
257+
{
258+
public function foo(string $s): string;
259+
260+
public function bar(int $i): int;
261+
}
262+
263+
// An abstract class may implement only a portion of an interface.
264+
// Classes that extend the abstract class must implement the rest.
265+
abstract class B implements A
266+
{
267+
pubic function foo(string $s): string
268+
{
269+
return $s . PHP_EOL;
270+
}
271+
}
272+
273+
class C extends B
274+
{
275+
public function bar(int $i): int
276+
{
277+
return $i * 2;
278+
}
279+
}
280+
?>
281+
]]>
282+
</programlisting>
283+
</example>
284+
<example xml:id="language.oop5.interfaces.examples.ex6">
285+
<title>Extending and implementing simultaneously</title>
286+
<programlisting role="php">
287+
<![CDATA[
288+
<?php
289+
290+
class One
291+
{
292+
/* ... */
293+
}
294+
295+
interface Usable
296+
{
297+
/* ... */
298+
}
299+
300+
interface Updatable
301+
{
302+
/* ... */
303+
}
304+
305+
// The keyword order here is important. 'extends' must come first.
306+
class Two extends One implements Usable, Updatable
215307
{
216-
const b = 'Class constant';
308+
/* ... */
217309
}
218310
?>
219311
]]>

0 commit comments

Comments
 (0)