OO avancé

Abstraction

  • En programmtion objet, il est possible de déclarer des méthodes dont la définition n’est pas encore connue dans la classe mère mais le seront dans une classe fille. On parle alors de méthodes abstraites. Une classe qui contient au moins une méthode abstraite doit elle aussi être déclarée abstraite et ne peut plus être instanciée - vu que tout son code n’est pas implémenté. On parle alors de classe abstraite.
  • Une méthode abstraite est précédée du mot clé abstract (idem pour la classe qui la porte) et ne peut pas avoir de corp.
Exemple de classe abstraite:

 <?php

 abstract class Animal
 {
     protected $nom;

     public function __construct($nom)
     {
         $this->nom = $nom;
     }

     abstract public function parler();
 }

 class Chien extends Animal
 {
     public function parler()
     {
         echo "$this->nom: Wouf Wouf\n";
     }
 }

 class Chat extends Animal
 {
     public function parler()
     {
         echo "$this->nom: Miaou\n";
     }
 }

 $chien = new Chien("Rex");
 $chien->parler(); // Rex: Wouf Wouf

 $chat = new Chat("Sac-a-puces");
 $chat->parler();  // Sac-a-puces: Miaou

Par opposition, une classe qui définit l’intégralité de ses comportements est souvent appellé classe concrête.

Interface

  • Une interface est un composant.
  • Une interface contient une ou plusieurs signature(s) de méthodes
  • Une classe peut implémenter 0, 1 ou plusieurs interfaces
  • Une classe qui implémente une interface doit implémenter (donner un corps à) chaque méthode de l’interface
<?php

interface estAffichable {
    function affiche();
}

interface estImprimable {
    function imprime($nbreFois);
}

abstract class Vehicule {
    public $nombreRoues;
    function affiche() {
        return "vehicule : nbre roues " . $this->nombreRoues;
    }
}

class Voiture extends Vehicule implements estAffichable, estImprimable {
    public $tailleCoffre;
    function imprime($nbreFois) {
        for ($i =0; $i < $nbreFois; $i++) {
            echo $this->affiche();
            echo "<br>";
        }
    }
    function affiche() {
        return parent::affiche() . " voiture : taille du coffre " .
                                        $this->tailleCoffre;
    }
}

$maVoiture = new Voiture();
$maVoiture->tailleCoffre=300;
$maVoiture->nombreRoues=4;
$maVoiture->imprime(2);
<?php

interface estAffichable {
    function affiche();
}

interface estImprimable {
    function imprime($nbreFois);
}

abstract class Vehicule {
    public $nombreRoues;
    function affiche() {
        return "vehicule : nbre roues " . $this->nombreRoues;
    }
}

class Voiture extends Vehicule implements estAffichable, estImprimable {
    public $tailleCoffre;
    function imprime($nbreFois) {
        for ($i =0; $i < $nbreFois; $i++) {
            echo $this->affiche();
            echo "<br>";
        }
    }
    function affiche() {
        return parent::affiche() . " voiture : taille du coffre " .
                                                $this->tailleCoffre;
    }
}

function imprimante(estImprimable $imprimable) { // prend une interface comme paramètre
    $imprimable->imprime(3);
}

$maVoiture = new Voiture();
$maVoiture->tailleCoffre=300;
$maVoiture->nombreRoues=4;

imprimante($maVoiture); // casting d'un objet dans son interface !!!

final

  • Classe « final » : ne pouvant pas avoir de sous-classe
  • Méthode « final » : ne pouvant pas être réécrite
final class Voiture {
    public $tailleCoffre;

    final function afficher() {
        echo "vehicule : nbre roues " . $this->nombreRoues;
    }
}

Static

  • Appel statique d’une méthode “classique” :
  • Appel de la méthode, sans passer par l’objet, directement sur la classe
  • La méthode ne doit pas contenir de $this (car pas défini, puisque pas d’objet)‏
  • Syntaxe : <classe>::<methode>()‏
<?php
class Voiture  {
    function test() {
        echo "test";
    }
}
echo Voiture::test();
  • Déclaration « static » d’un attribut ou d’une méthode

  • Éléments « static » ne sont appelables que sur la classe seulement

  • $this ne peut pas être employé (car pas défini, puisque pas d’objet)‏

  • $self désigne la classe elle-même

  • Syntaxe :
    • <classe>::<methode>()‏
    • <classe>::$<attribut>
<?php

class Voiture  {
    static $roues = 4;
    static function test() {
        return self::$roues;
    }
}

echo Voiture::$roues++; // update class attribute
echo Voiture::test();
// affiche 4 5

Constante de debug

  • Deux méta-constantes utiles pour le debug ou le tracing :
    • __CLASS__ : donne le nom de la classe courante
    • __METHOD__ : donne le nom de la méthode courante
<?php
class Voiture  {
    function test() {
        echo "classe : " . __CLASS__ . ", methode : " . __METHOD__ ;
    }
}
$voiture = new Voiture();
$voiture->test();

Affichage d’objet

  • Affichage direct d’un objet => erreur !
  • Utilisation de la méthode __toString() :
  • Ré-écrire cette méthode dans une classe
  • Affichage direct d’un objet de cette classe => exécution de la méthode __toString réécrite
<?php
class Voiture  {
    function __toString() {
        return "ceci est une voiture";
    }
}
$voiture = new Voiture();
echo $voiture;

Fonction de type d’objet

  • Vérifier qu’un objet appartient à une classe donnée ou à une de ses sous-classes
    • <objet> instance of <classe>
  • Donner la classe d’un objet :
    • get_class( )‏
  • Donner la classe père d’un objet :
    • get_parent_class( )‏

Méthodes magique

  • __sleep() et __wakeup() : permettent de gérer la mise en session d’objets connectés à des ressources externes (fichiers...)
  • __set($nom, $valeur) : méthode appelée lors de l’affectation d’une valeur à un attribut inexistant
  • __get($nom) : méthode appelée lors de la consultation d’un attribut inexistant (Mutator)‏
  • __call($nom, $valeur) : méthode appelée lors de l’appel de méthodes inexistantes ($valeur = 1 tableau de paramètres) (Accessor)‏

Autoload

  • __autoload($nom) :
  • Fonction appelée lors de l’instantiation d’un objet d’une classe inexistante
  • Le paramètre $nom est le nom de la classe manquante
  • Permet de charger automatiquement le fichier PHP
<?php
function __autoload($nom) {
    require_once($nom . ".class.php");
}

$voiture = new Voiture();
echo $voiture;

Attention, maintenant d’utiliser l’autoload de composer (PSR4).

Table des Matières

Sujet précédent

Polymorphisme

Sujet suivant

Namespace

Cette page