mirror of
https://github.com/macintoshplus/doc-fr.git
synced 2026-03-26 01:42:09 +01:00
360 lines
9.5 KiB
XML
360 lines
9.5 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 5d1673b7a0e1a941111595d25cda663d8667a015 Maintainer: yannick Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<sect1 xml:id="language.oop5.interfaces" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||
<title>Interfaces</title>
|
||
<para>
|
||
Les interfaces objet vous permettent de créer du code qui spécifie quelles
|
||
méthodes une classe doit implémenter, sans avoir à définir comment ces méthodes
|
||
fonctionneront. Les interfaces partagent l'espace de nom avec les classes
|
||
et les traits, donc elles ne peuvent pas utiliser le même nom.
|
||
</para>
|
||
<para>
|
||
Les interfaces sont définies de la même façon que pour une classe, mais en
|
||
utilisant le mot-clé <literal>interface</literal> à la place de
|
||
<literal>class</literal>, et sans qu'aucune des méthodes n'ait son contenu
|
||
de spécifié.
|
||
</para>
|
||
<para>
|
||
De par la nature même d'une interface, toutes les méthodes déclarées dans une
|
||
interface doivent être publiques.
|
||
</para>
|
||
<para>
|
||
En pratique les interfaces servent deux rôles complémentaires :
|
||
</para>
|
||
<simplelist>
|
||
<member>
|
||
Permettre aux développeurs de créer des objets de classes différentes
|
||
qui peuvent être utilisé de façon interchangeable, car elles implémentent
|
||
la ou les mêmes interfaces. Un exemple commun sont plusieurs services
|
||
d'accès à des bases de données, plusieurs gestionnaires de paiement ou
|
||
différentes stratégies de cache. Différentes implémentations peuvent être
|
||
échangées sans nécessiter des changements dans le code qui les utilisent.
|
||
</member>
|
||
<member>
|
||
Pour permettre à une fonction ou méthode d'accepter et opérer sur un
|
||
paramètre qui conforme à une interface, sans se soucier de quoi d'autre
|
||
l'objet peut faire ou comment c'est implémenté. Ces interfaces sont souvent
|
||
nommées <literal>Iterable</literal>, <literal>Cacheable</literal>, <literal>Renderable</literal>,
|
||
etc. pour décrire la signification de leur comportement.
|
||
</member>
|
||
</simplelist>
|
||
<para>
|
||
Les interfaces peuvent définir des
|
||
<link linkend="language.oop5.magic">méthodes magiques</link> pour obliger
|
||
les classes implémentant à implémenter ces méthodes.
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Tant bien que c'est supporté, inclure les
|
||
<link linkend="language.oop5.decon.constructor">constructeurs</link>
|
||
dans les interfaces et fortement déconseillé. Faire ceci réduit
|
||
radicalement la flexibilité des objets implémentant l'interface.
|
||
De plus, les constructeurs ne sont pas soumis aux règles d'héritage,
|
||
ce qui peut causer des incohérences et des comportements inattendus.
|
||
</para>
|
||
</note>
|
||
|
||
<sect2 xml:id="language.oop5.interfaces.implements">
|
||
<title><literal>implements</literal></title>
|
||
<para>
|
||
Pour implémenter une interface, l'opérateur <literal>implements</literal>
|
||
est utilisé. Toutes les méthodes de l'interface doivent être implémentées dans une
|
||
classe ; si ce n'est pas le cas, une erreur fatale sera émise. Les classes peuvent
|
||
implémenter plus d'une interface, en séparant chaque interface par une virgule.
|
||
</para>
|
||
<warning>
|
||
<para>
|
||
Une classe peut implémenter deux interfaces qui définissent une méthode
|
||
avec le même nom, seulement si la déclaration de la méthode est identique
|
||
dans les deux interfaces est identique.
|
||
</para>
|
||
</warning>
|
||
<warning>
|
||
<para>
|
||
Une classe qui implémente une interface peut utiliser des noms différents
|
||
pour ses paramètres que l'interface. Cependant, à partir de PHP 8.0, le
|
||
langage supporte les
|
||
<link linkend="functions.named-arguments">arguments nommés</link>, ce qui
|
||
signifie que l'appeleur peut dépendre du nom du paramètre dans l'interface.
|
||
Pour cette raison, il est fortement recommandé que les développeurs
|
||
utilisent le même nom de paramètre que dans l'interface qui est implémenté.
|
||
</para>
|
||
</warning>
|
||
<note>
|
||
<para>
|
||
Les interfaces peuvent être étendues comme des classes, en utilisant l'opérateur
|
||
<link linkend="language.oop5.inheritance">extends</link>
|
||
</para>
|
||
</note>
|
||
<note>
|
||
<para>
|
||
La classe implémentant l'interface doit déclarer toutes les méthodes dans
|
||
l'interface avec une <link linkend="language.oop.lsp">signature compatible</link>.
|
||
</para>
|
||
</note>
|
||
</sect2>
|
||
<sect2 xml:id="language.oop5.interfaces.constants">
|
||
<title><literal>Les constantes</literal></title>
|
||
<para>
|
||
Les interfaces peuvent contenir des constantes. Les constantes d'interfaces
|
||
fonctionnent exactement comme les
|
||
<link linkend="language.oop5.constants">constantes de classe</link>.
|
||
Antérieur à PHP 8.1.0, elles ne peuvent pas être redéfinies par une
|
||
classe/interface qui les hérite.
|
||
</para>
|
||
</sect2>
|
||
<sect2 xml:id="language.oop5.interfaces.examples">
|
||
&reftitle.examples;
|
||
<example xml:id="language.oop5.interfaces.examples.ex1">
|
||
<title>Exemple d'interface</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
// Declaration de l'interface 'Template'
|
||
interface Template
|
||
{
|
||
public function setVariable($name, $var);
|
||
public function getHtml($template);
|
||
}
|
||
|
||
// Implémentation de l'interface
|
||
// Ceci va fonctionner
|
||
class WorkingTemplate implements Template
|
||
{
|
||
private $vars = [];
|
||
|
||
public function setVariable($name, $var)
|
||
{
|
||
$this->vars[$name] = $var;
|
||
}
|
||
|
||
public function getHtml($template)
|
||
{
|
||
foreach($this->vars as $name => $value) {
|
||
$template = str_replace('{' . $name . '}', $value, $template);
|
||
}
|
||
|
||
return $template;
|
||
}
|
||
}
|
||
|
||
// Ceci ne fonctionnera pas
|
||
// Fatal error: Class BadTemplate contains 1 abstract methods
|
||
// and must therefore be declared abstract (Template::getHtml)
|
||
class BadTemplate implements Template
|
||
{
|
||
private $vars = [];
|
||
|
||
public function setVariable($name, $var)
|
||
{
|
||
$this->vars[$name] = $var;
|
||
}
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<example xml:id="language.oop5.interfaces.examples.ex2">
|
||
<title>Les interfaces extensibles</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
interface A
|
||
{
|
||
public function foo();
|
||
}
|
||
|
||
interface B extends A
|
||
{
|
||
public function baz(Baz $baz);
|
||
}
|
||
|
||
// Ceci fonctionnera
|
||
class C implements B
|
||
{
|
||
public function foo()
|
||
{
|
||
}
|
||
|
||
public function baz(Baz $baz)
|
||
{
|
||
}
|
||
}
|
||
|
||
// Ceci ne fonctionnera pas et entrainera une erreur fatale
|
||
class D implements B
|
||
{
|
||
public function foo()
|
||
{
|
||
}
|
||
|
||
public function baz(Foo $foo)
|
||
{
|
||
}
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<example xml:id="language.oop5.interfaces.examples.ex3">
|
||
<title>Héritage de plusieurs interfaces</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
interface A
|
||
{
|
||
public function foo();
|
||
}
|
||
|
||
interface B
|
||
{
|
||
public function bar();
|
||
}
|
||
|
||
interface C extends A, B
|
||
{
|
||
public function baz();
|
||
}
|
||
|
||
class D implements C
|
||
{
|
||
public function foo()
|
||
{
|
||
}
|
||
|
||
public function bar()
|
||
{
|
||
}
|
||
|
||
public function baz()
|
||
{
|
||
}
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<example xml:id="language.oop5.interfaces.examples.ex4">
|
||
<title>Interfaces avec des constantes</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
interface A
|
||
{
|
||
const B = 'Constante de l\'interface';
|
||
}
|
||
|
||
// Affiche : Constante de l'interface
|
||
echo A::B;
|
||
|
||
|
||
// Par contre, ceci ne fonctionnera pas, puisqu'il n'est pas permis
|
||
// d'écraser des constantes.
|
||
class B implements A
|
||
{
|
||
const B = 'Constante de classe';
|
||
}
|
||
|
||
// Affiche : Constante de classe
|
||
// Antérieur à PHP 8.1.0, ceci ne fonctionnera pas, puisqu'il n'était pas permis
|
||
// de redéfinir des constantes.
|
||
echo B::B;
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<example xml:id="language.oop5.interfaces.examples.ex5">
|
||
<title>Les interfaces avec les classes abstraites</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
interface A
|
||
{
|
||
public function foo(string $s): string;
|
||
|
||
public function bar(int $i): int;
|
||
}
|
||
|
||
// An abstract class may implement only a portion of an interface.
|
||
// Classes that extend the abstract class must implement the rest.
|
||
abstract class B implements A
|
||
{
|
||
public function foo(string $s): string
|
||
{
|
||
return $s . PHP_EOL;
|
||
}
|
||
}
|
||
|
||
class C extends B
|
||
{
|
||
public function bar(int $i): int
|
||
{
|
||
return $i * 2;
|
||
}
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<example xml:id="language.oop5.interfaces.examples.ex6">
|
||
<title>Étendant et implémentant simultanément</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class One
|
||
{
|
||
/* ... */
|
||
}
|
||
|
||
interface Usable
|
||
{
|
||
/* ... */
|
||
}
|
||
|
||
interface Updatable
|
||
{
|
||
/* ... */
|
||
}
|
||
|
||
// The keyword order here is important. 'extends' must come first.
|
||
class Two extends One implements Usable, Updatable
|
||
{
|
||
/* ... */
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<para>
|
||
Une interface, avec les déclarations de types, fournit une bonne manière
|
||
pour s'assurer qu'un objet particulier contient des méthodes particulières.
|
||
Voir l'opérateur <link linkend="language.operators.type">instanceof</link> et
|
||
les <link linkend="language.types.declarations">déclarations de type</link>.
|
||
</para>
|
||
</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
|
||
-->
|