<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.oop5.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'fr',
  ),
  'this' => 
  array (
    0 => 'language.oop5.abstract.php',
    1 => 'Abstraction de classes',
    2 => 'Abstraction de classes',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Les classes et les objets',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.static.php',
    1 => 'Statique',
  ),
  'next' => 
  array (
    0 => 'language.oop5.interfaces.php',
    1 => 'Interfaces',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'fr',
    'path' => 'language/oop5/abstract.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.abstract" class="sect1">
 <h2 class="title">Abstraction de classes</h2>
 
 <p class="para">
  PHP a des classes, méthodes et propriétés abstraites.
  Les classes définies comme abstraites ne peuvent pas être
  instanciées, et toute classe contenant au moins une
  méthode abstraite ou propriété abstraite doit elle aussi être abstraite.
  Les méthodes définies comme abstraites se contentent de déclarer la signature de la méthode et d&#039;indiquer si elle est publique ou protégée ;  
  elles ne peuvent pas définir l&#039;implémentation. Les propriétés définies comme abstraites  
  peuvent déclarer une exigence pour le comportement de <code class="literal">get</code> ou de <code class="literal">set</code>,  
  et peuvent fournir une implémentation pour l&#039;une de ces opérations, mais pas les deux.
 </p>
 
 <p class="para">
  Lors de l&#039;héritage d&#039;une classe abstraite, toutes les méthodes
  marquées comme abstraites dans la déclaration de la classe parente
  doivent être définies par la classe enfant et suivre les règles habituelles
  d&#039;<a href="language.oop5.inheritance.php" class="link">héritage</a> et de
  <a href="language.oop5.basic.php#language.oop.lsp" class="link">compatibilité de signature</a>.
 </p>

 <p class="simpara">
  À partir de PHP 8.4, une classe abstraite peut déclarer une propriété abstraite, publique ou protégée.
  Une propriété abstraite protégée peut être satisfaite par une propriété accessible en lecture/écriture
  depuis un contexte protégé ou public.
 </p>
 <p class="simpara">
  Une propriété abstraite peut être satisfaite soit par une propriété standard, soit par une propriété
  avec des <a href="language.oop5.property-hooks.php" class="link">hooks</a> définis, correspondant à l&#039;opération requise.
 </p>

 <div class="example" id="example-1">
  <p><strong>Exemple #1 Exemple de méthode abstraite</strong></p>
  <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">AbstractClass <br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Force les classes filles à définir cette méthode<br />    </span><span style="color: #007700">abstract protected function </span><span style="color: #0000BB">getValue</span><span style="color: #007700">();<br />    abstract protected function </span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">);<br /><br />    </span><span style="color: #FF8000">// méthode commune<br />   </span><span style="color: #007700">public function </span><span style="color: #0000BB">printOut</span><span style="color: #007700">()<br />   {<br />        print </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getValue</span><span style="color: #007700">() . </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />   }<br />}<br /><br />class </span><span style="color: #0000BB">ConcreteClass1 </span><span style="color: #007700">extends </span><span style="color: #0000BB">AbstractClass <br /></span><span style="color: #007700">{<br />     protected function </span><span style="color: #0000BB">getValue</span><span style="color: #007700">()<br />     {<br />       return </span><span style="color: #DD0000">"ConcreteClass1"</span><span style="color: #007700">;<br />     }<br /><br />     public function </span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">)<br />     {<br />       return </span><span style="color: #DD0000">"</span><span style="color: #007700">{</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">}</span><span style="color: #DD0000">ConcreteClass1"</span><span style="color: #007700">;<br />     }<br />}<br /><br />class </span><span style="color: #0000BB">ConcreteClass2 </span><span style="color: #007700">extends </span><span style="color: #0000BB">AbstractClass <br /></span><span style="color: #007700">{<br />     public function </span><span style="color: #0000BB">getValue</span><span style="color: #007700">()<br />     {<br />       return </span><span style="color: #DD0000">"ConcreteClass2"</span><span style="color: #007700">;<br />     }<br /><br />     public function </span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">)<br />     {<br />       return </span><span style="color: #DD0000">"</span><span style="color: #007700">{</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">}</span><span style="color: #DD0000">ConcreteClass2"</span><span style="color: #007700">;<br />     }<br />}<br /><br /></span><span style="color: #0000BB">$class1 </span><span style="color: #007700">= new </span><span style="color: #0000BB">ConcreteClass1</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$class1</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printOut</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$class1</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #DD0000">'FOO_'</span><span style="color: #007700">), </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$class2 </span><span style="color: #007700">= new </span><span style="color: #0000BB">ConcreteClass2</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$class2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printOut</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$class2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #DD0000">'FOO_'</span><span style="color: #007700">), </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>

  <div class="example-contents"><p>L&#039;exemple ci-dessus va afficher :</p></div>
  <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
</pre></div>
  </div>
 </div>

  <div class="example" id="example-2">
   <p><strong>Exemple #2 Exemple de méthode abstraite</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">AbstractClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Une méthode abstraite ne doit que définir les arguments requis<br />    </span><span style="color: #007700">abstract protected function </span><span style="color: #0000BB">prefixName</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br /><br />}<br /><br />class </span><span style="color: #0000BB">ConcreteClass </span><span style="color: #007700">extends </span><span style="color: #0000BB">AbstractClass<br /></span><span style="color: #007700">{<br /><br />    </span><span style="color: #FF8000">// Une classe enfant peut définir des arguments optionnels qui ne sont pas présents dans la signature du parent<br />     </span><span style="color: #007700">public function </span><span style="color: #0000BB">prefixName</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$separator </span><span style="color: #007700">= </span><span style="color: #DD0000">"."</span><span style="color: #007700">)<br />     {<br />        if (</span><span style="color: #0000BB">$name </span><span style="color: #007700">== </span><span style="color: #DD0000">"Pacman"</span><span style="color: #007700">) {<br />            </span><span style="color: #0000BB">$prefix </span><span style="color: #007700">= </span><span style="color: #DD0000">"Mr"</span><span style="color: #007700">;<br />        } elseif (</span><span style="color: #0000BB">$name </span><span style="color: #007700">== </span><span style="color: #DD0000">"Pacwoman"</span><span style="color: #007700">) {<br />            </span><span style="color: #0000BB">$prefix </span><span style="color: #007700">= </span><span style="color: #DD0000">"Mrs"</span><span style="color: #007700">;<br />        } else {<br />            </span><span style="color: #0000BB">$prefix </span><span style="color: #007700">= </span><span style="color: #DD0000">""</span><span style="color: #007700">;<br />        }<br /><br />        return </span><span style="color: #DD0000">"</span><span style="color: #007700">{</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">}{</span><span style="color: #0000BB">$separator</span><span style="color: #007700">}</span><span style="color: #DD0000"> </span><span style="color: #007700">{</span><span style="color: #0000BB">$name</span><span style="color: #007700">}</span><span style="color: #DD0000">"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$class </span><span style="color: #007700">= new </span><span style="color: #0000BB">ConcreteClass</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$class</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefixName</span><span style="color: #007700">(</span><span style="color: #DD0000">"Pacman"</span><span style="color: #007700">), </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$class</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefixName</span><span style="color: #007700">(</span><span style="color: #DD0000">"Pacwoman"</span><span style="color: #007700">), </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>L&#039;exemple ci-dessus va afficher :</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Mr. Pacman
Mrs. Pacwoman
</pre></div>
   </div>
  </div>
  <div class="example" id="example-3">
   <p><strong>Exemple #3 Exemple de propriété abstraite</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Les classes dérivées doivent avoir une propriété publiquement accessible en lecture.<br />    </span><span style="color: #007700">abstract public </span><span style="color: #0000BB">string $readable </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get</span><span style="color: #007700">;<br />    }<br /><br />    </span><span style="color: #FF8000">// Les classes dérivées doivent avoir une propriété modifiable en écriture, protégée ou publique.<br />     </span><span style="color: #007700">abstract protected </span><span style="color: #0000BB">string $writeable </span><span style="color: #007700">{<br />         </span><span style="color: #0000BB">set</span><span style="color: #007700">;<br />    }<br /><br />    </span><span style="color: #FF8000">// Les classes dérivées doivent avoir une propriété symétrique protégée ou publique.<br />     </span><span style="color: #007700">abstract protected </span><span style="color: #0000BB">string $both </span><span style="color: #007700">{<br />         </span><span style="color: #0000BB">get</span><span style="color: #007700">;<br />         </span><span style="color: #0000BB">set</span><span style="color: #007700">;<br />     }<br />}<br /><br />class </span><span style="color: #0000BB">C </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Cela satisfait l'exigence et rend également la propriété modifiable, ce qui est valide.<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">string $readable</span><span style="color: #007700">;<br /><br />    </span><span style="color: #FF8000">// Cela NE satisferait PAS l'exigence, car la propriété n'est pas publiquement accessible en lecture.<br />    </span><span style="color: #007700">protected </span><span style="color: #0000BB">string $readable</span><span style="color: #007700">;<br /><br />    </span><span style="color: #FF8000">// Cela satisfait exactement l'exigence, donc c'est suffisant.<br />    // La propriété ne peut être modifiée qu'à partir d'un contexte protégé.<br />    </span><span style="color: #007700">protected </span><span style="color: #0000BB">string $writeable </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />    }<br /><br />    </span><span style="color: #FF8000">// Cela élargit la visibilité de protégé à public, ce qui est acceptable.<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">string $both</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Une propriété abstraite dans une classe abstraite peut fournir des implémentations pour tout hook,
   mais doit avoir soit <code class="literal">get</code> soit <code class="literal">set</code> déclarés mais non définis (comme dans l&#039;exemple ci-dessus).
  </p>
  <div class="example" id="example-4">
   <p><strong>Exemple #4 Exemple de propriété abstraite avec des hooks</strong></p>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Cela fournit une implémentation par défaut (mais substituable) pour set,<br />    // et exige que les classes dérivées fournissent une implémentation pour get.<br />    </span><span style="color: #007700">abstract public </span><span style="color: #0000BB">string $foo </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get</span><span style="color: #007700">;<br /><br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">{<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />        }<br />    }<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
</div><?php manual_footer($setup); ?>