IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

interfaces : définition de implémentation et de utilisation [POO]


Sujet :

Langage PHP

  1. #1
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 486
    Billets dans le blog
    1
    Par défaut interfaces : définition de implémentation et de utilisation
    Bonsoir,

    toujours dans mon étude de la POO, j'en suis aux interfaces et y a 2 notions que je n'arrive pas à appréhender : car il est dit qu'une classe peut implémenter une interface ou utiliser une interface.
    L'implémentation, selon ce que j'ai compris, fournit des signatures de méthodes, et les classes qui implémentent l'interface doivent les définir (donc donner le contenu de ces méthodes).
    Par contre, j'ai vu qu'une classe pouvait aussi utiliser une interface. Qu'elle est la différence avec implémenter ?

  2. #2
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 486
    Billets dans le blog
    1
    Par défaut
    Ce que j'ai compris : ça implémente la notion d'entrées-sorties.

    Si la classe A implémente l'interface I1, il s'agit des sorties de la classe A. En effet, la classe A reprend les signatures de méthodes fournies par l'interface I1, les définit (elle fournit leur contenu) et offre en sorties ces méthodes.

    Si la classe A utilise l'interface I2, ça veut dire qu'elle utilise les méthodes d'un objet qui est l'instance d'une autre classe qui implémente l'interface I2. Il s'agit donc d'entrées de la classe A.

    Ai-je bien compris les notions d'implémentation et d'utilisation d'interfaces ?

  3. #3
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    ta première assertion est exacte, la seconde est fausse.

    Implémenter, dans le cadre informatique veut dire "fournir une fonctionnalité".
    Donc quand on parle qu'une classe implémente une interface (ou même plusieurs interfaces), cela veut dire que la classe doit fournir les fonctionnalités décrites dans ces interfaces.
    C'est comme si l'interface te forçait à fournir des fonctionnalités (à implémenter) par contrat.

    On va prendre un exemple directement du PHP :
    Tu as une classe qui doit fonctionner comme un tableau et être utilisable comme un tableau : renvoyer une valeur avec la fonction count() et avoir la possibilité de gérer des valeurs avec une définition [].
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Foo
    {
     
    }
     
    $a = new Foo();
     
    $b = count($a);   // Warning: count(): Parameter must be an array or an object that implements Countable
    $a[] = 'abc';     // PHP Fatal error:  Uncaught Error: Cannot use object of type Foo as array in
    Si tu veux fournir des propriétés équivalentes à un tableau à un objet, PHP t'indique dans la documentation qu'il existe une interface Countable et une autre ArrayAccess.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     Countable {
    /* Methods */
    abstract public count ( void ) : int
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     ArrayAccess {
    /* Methods */
    abstract public offsetExists ( mixed $offset ) : bool
    abstract public offsetGet ( mixed $offset ) : mixed
    abstract public offsetSet ( mixed $offset , mixed $value ) : void
    abstract public offsetUnset ( mixed $offset ) : void
    }
    Donc tu sais que si tu veux que ta classe se comporte comme un tableau tu dois implémenter ces deux interfaces et définir le corps des fonctions abstraites qui y sont respectivement rattachées :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    class Foo
    implements ArrayAccess, Countable
    {
        private $container = [];
     
        public function offsetSet($offset, $value) {
            if ($offset === null) {
                $this->container[] = $value;
            } else {
                $this->container[$offset] = $value;
            }
        }
     
        public function offsetExists($offset) {
            return isset($this->container[$offset]);
        }
     
        public function offsetUnset($offset) {
            unset($this->container[$offset]);
        }
     
        public function offsetGet($offset) {
            return isset($this->container[$offset]) ? $this->container[$offset] : null;
        }
     
        /**
         * Count elements of an object
         * @link  https://php.net/manual/en/countable.count.php
         * @return int The custom count as an integer.
         * </p>
         * <p>
         * The return value is cast to an integer.
         * @since 5.1.0
         */
        public function count()
        {
            return count($this->container);
        }
    }
    et maintenant, ceci devient possible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $a = new Foo();
    $a[] = 'abc';
    $a[] = 'def';
    $a['25'] = 225;
    $b = count($a); // 3
    L'usage des interfaces est très pratique car cela rend certain l'implémentation des fonctionnalités décrites par lesdites interfaces par ce qui est manipulé.

  4. #4
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 486
    Billets dans le blog
    1
    Par défaut
    Merci pour ton explication.

    Tu donnes le code des 2 interfaces : Countable et ArrayAccess. Ne faut-il pas le mot-clé interface ? Et le mot-clé abstract devant les méthodes est-il nécessaire ?

    Sinon, tu me dis que ma deuxième assertion est fausse, mais peux-tu me dire ce qui serait juste ?

  5. #5
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Tu donnes le code des 2 interfaces : Countable et ArrayAccess. Ne faut-il pas le mot-clé interface ? Et le mot-clé abstract devant les méthodes est-il nécessaire ?
    Le code donné par rawsrc n'est qu'un synopsis issue de la doc pas le code réel. Si c'était une interface PHP il faudrait effectivement qu'elle commence avec interface.

    En PHP les fonction d'une interface son abstract par défaut. Utiliser abstract devant leur nom n'est donc pas obligatoire.

    Sinon, tu me dis que ma deuxième assertion est fausse, mais peux-tu me dire ce qui serait juste ?
    La notion "d'utiliser" une interface n'existe pas vraiment. On l'implémente c'est tout. C'est juste une façon différente de le dire.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 486
    Billets dans le blog
    1
    Par défaut
    Ok ,
    Je n'ai plus le bouquin sous les yeux mais je me souviens qu'il y avait une différence entre implémentation et utilisation vu que implémentation était considéré comme une sortie de la classe alors que utilisation était une entrée...

  7. #7
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    vu que implémentation était considéré comme une sortie de la classe alors que utilisation était une entrée...
    Mais de quoi tu parles ?

    Une interface est un type d'objet qui oblige une classe qui l'implémente à fournir certaines fonctionnalités.
    Une fonctionnalité au sens générique.

  8. #8
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Bonjour,
    En supposant qu'il s'agisse du même livre que dans cet autre sujet, je pense qu'il faut faire la part entre :

    1) D'un côté, les formulations à caractère universel correspondant à des concepts/mécanismes précis de la programmation.
    Exemples :
    a) "Redéfinition de méthode" (en référence à l'autre sujet).
    b) "Implémentation d'une interface".

    2) D'un autre, les formulations davantage propres à l'auteur correspondant à des descriptions plus ou moins vagues de procédés/possibilités.
    Exemples :
    a) "Remplacement d'un mot clé" (en référence à l'autre sujet).
    b) "Utilisation d'une interface".
    Pour développer sur une signification possible :
    Citation Envoyé par laurentSc Voir le message
    Si la classe A utilise l'interface I2, ça veut dire qu'elle utilise les méthodes d'un objet qui est l'instance d'une autre classe qui implémente l'interface I2.
    Par exemple, dans une classe A, une méthode pourrait avoir comme paramètre un objet avec, pour type requis, l'interface I2 implémentée par la classe de cet objet.
    Cette méthode pourrait alors utiliser une méthode de l'objet passé en paramètre.
    Si on veut, on peut alors dire, en version très résumée, que la classe A utilise l'interface I2.
    Mais c'est une utilisation très indirecte.
    Ce n'est pas comme si on utilisait l'interface avec un mot clé comme "use".
    Cette formulation n'est pas comparable à "une classe implémente une interface" qui a une signification précise et directe.

    De même pour cette comparaison "entrées/sorties", c'est juste une vision des choses, un simple point de vue...

  9. #9
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 486
    Billets dans le blog
    1
    Par défaut
    Je crois que Loralina a compris de quoi je parle. Dimanche, quand j'aurai de nouveau le bouquin sous les yeux je donnerai l'exemple de code en PHP....

  10. #10
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 486
    Billets dans le blog
    1
    Par défaut
    Voici l'exemple de code PHP des notions d'entrées/sorties, donné dans le bouquin de Bersini sur la POO :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <?php
    interface I01 {
        public function jeTravaillePour01();
    }
    interface I02 {
        public function jeTravaillePour02();
    }
     
    class 01 implements I01 {
        private $un02;
        public function __construct()  {}
        public function set02(I02 $un02) {
            $this->un02 = $un02;
        }
        public function jUtilise02(){
            print("j'utilise 02<br/> \n");
            $this->un02->jeTravaillePour02();
        }
        public function jeTravaillePour01(){
           print("je travaille pour 01<br/> \n");
           self::jImplementeLeService01();
        }
        private function jImplementeLeService01(){
            print("je suis privé dans 01 <br/> \n");
        }
    }
     
    class 02 implements I02 {
        private $un01;
        public function __construct(I01 $un01)  {
            $this->un01 = $un01;
        }
        public function jeTravaillePour02(){
           print("je travaille pour 02<br/> \n");
           self::jImplementeLeService02();
        }
         public function jUtilise01(){
            print("j'utilise 01<br/> \n");
            $this->un01->jeTravaillePour01();
        }
        private function jImplementeLeService02(){
            print("je suis privé dans 02 <br/> \n");
        }
    }
     
    $un01 = new 01();
    $un02 = new 02($un01);
    $un01->set02($un02);
    $un01->jUtilise02();
    $un02->jUtilise01();
    ?>

    Merci de me dire si Loralina a bien vu ma compréhension de ce que Bersini appelle une entrée de la classe 01.

  11. #11
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    non mais c'est quoi cet exemple vaseux ? Tu m'étonnes que la POO soit absconse
    Donne moi la page dans le livre stp

  12. #12
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 486
    Billets dans le blog
    1
    Par défaut
    Dans la 7e édition du bouquin (sortie en 2017), l'exemple est dans le chapitre 15, aux pages 384 et 385.

    [EDIT] et page 385, commence un sous-chapitre sur l'UML2, le concept d'entrées/sorties étant décrit dans cette dernière version de l'UML (cf notamment les diagrammes de "structure composite")

  13. #13
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Ok, je l'ai retrouvé dans ma version vieille d'il y a plus de 10 ans !
    Bon, je dois reconnaître que c'est assez tordu. Tu es dans un chapitre qui aborde l'héritage multiple. Comme c'est impossible en PHP et dans 90% des langages, on contourne la limitation par une grosse cuisine sur les interfaces.

    Premier point :
    Ce que tu dois bien mémoriser c'est qu'une interface n'est rien d'autre qu'un contrat qui oblige une classe à fournir le code nécessaire pour remplir ce contrat.
    L'interface va se limiter qu'à fournir une liste de signature de fonctions et ça sera à la classe à fournir le code correspondant.

    Deuxième point :
    Une interface est aussi un type : c'est à dire que tu peux exiger qu'un objet en paramètre implémente une interface particulière.
    Au même titre que lorsque tu fais function foo(array $p), tu peux très bien faire function foo(InterfaceA $p) dans ce second cas, le moteur PHP vérifiera que $p implémente l'interface InterfaceA. Ainsi tu auras la certitude que $p possédera les fonctionnalités définies par l'interface InterfaceA.

    Troisième point :
    Comme une interface est aussi un type, tu peux très bien l'avoir en retour d'une fonction typée : function foo(array $p): InterfaceA { }.

    Quatrième point :
    Comme une interface est aussi un objet, tu peux très bien l'étendre comme une classe, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    interface InterfaceA {
     
    }
     
    interface InterB
    extends InterfaceA {
     
    }
    L'intérêt des interface réside dans la programmation générique que cela offre.
    Tu peux très bien définir le squelette d'une application intégralement avec des interfaces et laisser ensuite à d'autre programmeurs le soin de coder les classes qui vont les implémenter et fournir le code nécessaire à leur exécution.
    Quand tu travailles avec des interfaces, tu fais de l'architecture logicielle.

    Il y a des années de ça, avec des collègues on avait pris le pari de designer une application intégralement qu'avec des interfaces. C'était bizarre, on n'a jamais parlé de code mais juste d'architecture, modélisation, abstraction fonctionnelle.

  14. #14
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 486
    Billets dans le blog
    1
    Par défaut
    Merci pour tes éclaircissements.

    Tu parles du typage des données en entrée ou sortie des fonctions. Concernant PHP, ce n'est bien apparu qu'en PHP7, non ?

  15. #15
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Pas tout à fait, déjà en PHP 5.3+, il était possible de typer certains paramètres : function foo(array $p, MaClasseAMoi $c, MonInterfaceAToi $i), par contre le typage de retour n'est apparu qu'avec PHP 7 ainsi que le typage primitif : string, int, bool

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Définition de classes et leur utilisation avec des List
    Par Tahiti-Bob dans le forum C#
    Réponses: 10
    Dernier message: 14/11/2017, 23h35
  2. [XL-2007] Problème dans la définition de la dernière ligne utilisée
    Par Runsh63 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 15/02/2016, 16h41
  3. Programmation - Définition de variables complexes et utilisation
    Par Tarrke dans le forum Programmation (La)TeX avancée
    Réponses: 2
    Dernier message: 19/03/2012, 09h49
  4. Réponses: 4
    Dernier message: 29/04/2010, 09h48
  5. interface graphique utilisateur, que faut-il utiliser?
    Par Missvan dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 01/03/2004, 12h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo