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 :

Interface, classe abstraite et typage des paramètres de méthode


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif

    Homme Profil pro
    Concepteur d'applications web
    Inscrit en
    Avril 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur d'applications web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2003
    Messages : 102
    Par défaut Interface, classe abstraite et typage des paramètres de méthode
    Salut,

    J'avais déjà dû le voir, mais maintenant ça me choque.
    Imaginons :
    une interface "say" qui déclare une méthode "hello".
    une classe "behavior" qui implémente cette interface et qui déclare aussi une méthode public "byebye"
    une classe "person" qui a une propriété "protected $_behavior" et un setter "public function setBehavior(say $behaviorSay)" et un getter "public function getBehavior()"

    A votre avis, dans setBehavior() qu'est ce que je peux faire ?

    tic, tac, tic, tac
    attention l'heure tourne.

    petit indice je fais un print_r/var_dump sur $behavior et PHP va m'afficher "behavior Object()"

    tic, tac, tic, tac

    Et bien, PHP m'autorise à utiliser la méthode "byebye" alors même qu'elle n'est pas déclarée dans l'interface "say".

    Perso, ça me semble anormal car ça permet aux développeurs de faire ce qu'ils veulent dès lors que c'est public et ce, même si on a tenté de brider via un typage de paramètre. Evidemment je sais qu'on ne peut pas typer une propriété, du coup quand on appel le getter getBehavior(), je sais que j'aurais accès à tous ce qui est public dans l'objet qui a été injecté (au niveau de l'IDE si les commentaires sont bons on peut ~typer la propriété et brider l'autocomplétion proposé). Mais quand cela est possible aussi dans la méthode qui n'est censé utiliser que l'implémentation de l'interface, là ça me gène.

    Je suis seul à penser ça ? j'ai raté quelque chose ? je me pose trop de question ? je me pose les mauvaises questions ?

    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
     
    interface say {
        public function hello();
    };
     
    interface move {
        public function walk();
    }
     
    class behavior implements say, move{
        public function hello(){echo 'hello';}
        public function byebye(){echo 'bye bye';}
        public function walk(){echo 'i am walking';}
    };
     
    $a = new behavior;
     
    class person {
        /**
         * permet de brider l'auto-complétion de l'IDE sur les méthodes disponibles dans l'interface say
         * @var say
         */
        protected $_behavior;
        public function setBehavior(say $behavior){ 
            $this->_behavior = $behavior; 
     
            // ne devrait pas être accessible
            $behavior->byebye() ou $behavior->walk(); // ceci est autorisé en php alors que cette méthode n'est pas déclarée dans l'interface say
        }
     
        // on ne peut pas typer une propriété, du coup il est normal que cet getter permette ensuite d'accéder aux méthodes byebye et walk puisque de manière dynamique on a stocker un objet de type behavior
        public function getBehavior() { 
            return $this->_behavior; 
        }
    }
    PS : c'est la même chose si on utilise une classe abstraite et que l'on se sert de cette classe pour typer le paramètre : c'est le type de l'objet qui prime.
    Du coup le typage des paramètres sert à controller le type au niveau de l'entré alors qu'il devrait permettre également de controller l'utilisation de l'objet au sein de la méthode.

  2. #2
    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 : 50
    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
    Bonjour,
    Citation Envoyé par rebolon Voir le message
    Et bien, PHP m'autorise à utiliser la méthode "byebye" alors même qu'elle n'est pas déclarée dans l'interface "say".
    Je ne vois pas où est le problème. Une interface est un contrat, donc l'interface say te garantit qu'au minimum, les classes l'implémentant rempliront le contrat. Il n'y a aucune autre notion attachée.
    Donc après, si dans le corps de ta fonction tu appelles une fonction qui n'a rien à voir avec l'interface implémentée, c'est à tes risques et périls, rien ne peut te garantir effectivement que la fonction sera disponible.

  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 : 50
    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
    Après il est tout à fait possible d'étendre une interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    interface say {
       public function hello();
    };
     
    interface sayAndMove
       extends say
    {
       public function walk();
    }

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    Après il est tout à fait possible d'étendre une interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    interface say {
       public function hello();
    };
     
    interface sayAndMove
       extends say
    {
       public function walk();
    }
    on peut même faire plusieurs extends (ça marche que pour les interfaces)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    interface sayAndMove extends say, hello, blabla

  5. #5
    Membre actif

    Homme Profil pro
    Concepteur d'applications web
    Inscrit en
    Avril 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur d'applications web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2003
    Messages : 102
    Par défaut
    Ce qui me dérange c'est que la méthode puisse utiliser n'importe quelles méthodes public de l'objet passé. Le problème ? dans ce cas si ma méthode est utilisé à différents endroits ou dans différents projets et que les objets passés dans ces cas n'ont pas les fameuses méthodes public non déclarées dans l'interface, et bien ça va planter.

    Sauf erreur de ma part en Java ou dotNet on a accès uniquement aux méthodes déclarées dans l'interface.

    Bizarrement j'ai l'impression que ça fonctionnait comme ça, mais il est bien possible que je confonde avec d'autres langages.
    Dans le bouquin PHP Objects, Patterns, and Practice (édition APRESS) page 47/48 ils disent bien que la méthode n'a connaissance que des méthodes déclarées dans l'interface... Mais en fait elle a accès à beaucoup plus.

    Après si on veut utiliser la reflection, pour accéder à plus, on est libre de faire ce qu'on veut, mais dans ce cadre bien défini.

  6. #6
    Membre actif

    Homme Profil pro
    Concepteur d'applications web
    Inscrit en
    Avril 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur d'applications web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2003
    Messages : 102
    Par défaut
    D'accord avec l'héritage d'interface, mais ça ne modifie en rien la problématique.
    Autant supprimer les interfaces et typer avec la classe. Toute classe héritant de celle-ci seront autorisées (mais on a un couplage fort que les interfaces permettent d'éviter).

  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 : 50
    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 rebolon Voir le message
    Dans le bouquin PHP Objects, Patterns, and Practice (édition APRESS) page 47/48 ils disent bien que la méthode n'a connaissance que des méthodes déclarées dans l'interface... Mais en fait elle a accès à beaucoup plus.
    Oui tu as accès à la totalité de l'instance passée en paramètre.

    Citation Envoyé par rebolon Voir le message
    Après si on veut utiliser la reflection, pour accéder à plus, on est libre de faire ce qu'on veut, mais dans ce cadre bien défini.
    C'est pas la solution optimale dans la mesure où la réflection est lente et assez gourmande.

  8. #8
    Membre actif

    Homme Profil pro
    Concepteur d'applications web
    Inscrit en
    Avril 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur d'applications web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2003
    Messages : 102
    Par défaut
    Encore d'accord avec toi avec la Reflection, c'était juste pour dire que dans le principe où on aurait accès qu'aux méthodes de l'interface, la Reflection permettrait quand à ceux qui le souhaitent d'accéder au reste de l'instance envoyé.

    Au final c'est peut être un faux problème. Dans mon code je n'utilise que ce qui est proposé par l'interface (ou les classes abstraites, au pire)...

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    Quel est l’intérêt de faire du PHP si tu veux du typage fort ?

  10. #10
    Membre actif

    Homme Profil pro
    Concepteur d'applications web
    Inscrit en
    Avril 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur d'applications web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2003
    Messages : 102
    Par défaut
    Industrialiser mes dév !
    Eviter les régressions, même en PHP, c'est un truc sympa.

    Plus sérieusement, on peut vouloir du typage fort dans PHP parce que c'est simplement la plateforme sur laquelle on travaille. Mais cela n'empêche pas non plus d'utiliser les propriétés dynamiques de PHP.

    Attention, j'aime bien PHP, je dis juste que si PHP permet de typer les paramètres, autant qu'il respecte certains principe. Et, tant qu'à faire, autant que les bouquins évitent d'écrire des bêtises.

Discussions similaires

  1. [PHP 5.4] Typage des paramètres d'une classe abstraite
    Par comode dans le forum Langage
    Réponses: 8
    Dernier message: 18/04/2014, 19h34
  2. que choisir : interface, classe abstraite?
    Par kaibaa dans le forum Débuter
    Réponses: 4
    Dernier message: 04/11/2009, 23h19
  3. [PHP 5.3] Typage des paramètres d'une fonction pour ou contre
    Par berceker united dans le forum Langage
    Réponses: 6
    Dernier message: 09/07/2009, 15h34
  4. Interfaces/Classes abstraites et méthodes statiques
    Par Zakapatul dans le forum VB.NET
    Réponses: 7
    Dernier message: 06/01/2009, 14h38
  5. Réponses: 6
    Dernier message: 27/07/2005, 09h06

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