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 :

Fatal error: Non-abstract method function() must contain body [PHP 5.3]


Sujet :

Langage PHP

  1. #1
    Rédacteur

    Homme Profil pro
    Technical Lead Salesforce
    Inscrit en
    Février 2009
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Technical Lead Salesforce

    Informations forums :
    Inscription : Février 2009
    Messages : 563
    Points : 1 667
    Points
    1 667
    Par défaut Fatal error: Non-abstract method function() must contain body
    Bonjour, je développe une application où j'ai des classes qui héritent d'autres classes.

    Sur une de mes classes abstraites, j'ai déclaré une fonction protected mais seulement son entête car elle a deux classes filles qui utiliseront celle-ci, j'ai donc fais comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    abstract class A {
       ...
       protected function addResult($datas);
       ...
    }
     
    class B extends A{
       ...
       private function addResult($datas){
     
       }
    }
    Au moment du chargement de ma page, j'obtiens cette erreur:
    Fatal error: Non-abstract method function() must contain body
    Je comprends que les méthodes non abstraites doivent contenir un corps, ca voudrait dire que ce que je fais n'est pas bon et qu'il faudrait plutôt que je fasse une interface?

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    alors plusieurs choses à voir

    1 : écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected function addResult($datas){}
    en place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     protected function addResult($datas);
    cela dit tu ne peu pas utiliser addResult dans Class B , avec une méthode private : soit protected soit public, ou bien inverser le sens de lecture et rendre la fonction dans class A protected et dans Class B private

  3. #3
    Expert éminent sénior
    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
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    C'est tout à fait normal. Si tu veux forcer la définition d'une fonction dans une classe enfant il faut la noter abstract, comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    abstract class A {
       ...
       abstract protected function addResult($datas);
       ...
    }
    Tu n'auras plus de message d'erreur mais la classe héritant de cette dernière devra obligatoirement la redéfinir tout en conservant son prototype initial ou en augmentant sa visbilité.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class B extends A {
     
       /**
        * la visibilité ici de la fonction peut être :
        * protected ou public mais pas private
        */
       protected function addResult($data) {
          ...
          ...
       }
    }

  4. #4
    Rédacteur

    Homme Profil pro
    Technical Lead Salesforce
    Inscrit en
    Février 2009
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Technical Lead Salesforce

    Informations forums :
    Inscription : Février 2009
    Messages : 563
    Points : 1 667
    Points
    1 667
    Par défaut
    Citation Envoyé par ascito Voir le message
    alors plusieurs choses à voir

    1 : écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected function addResult($datas){}
    en place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     protected function addResult($datas);
    cela dit tu ne peu pas utiliser addResult dans Class B , avec une méthode private : soit protected soit public, ou bien inverser le sens de lecture et rendre la fonction dans class A protected et dans Class B private


    Citation Envoyé par rawsrc Voir le message
    Bonjour,

    C'est tout à fait normal. Si tu veux forcer la définition d'une fonction dans une classe enfant il faut la noter abstract, comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    abstract class A {
       ...
       abstract protected function addResult($datas);
       ...
    }
    Tu n'auras plus de message d'erreur mais la classe héritant de cette dernière devra obligatoirement la redéfinir tout en conservant son prototype initial ou en augmentant sa visbilité.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class B extends A {
     
       /**
        * la visibilité ici de la fonction peut être :
        * protected ou public mais pas private
        */
       protected function addResult($data) {
          ...
          ...
       }
    }
    Je ne sais pas trop qui suivre.

    Si je te suis rawsrc, il suffit que je mette abstract devant ma fonction de ma class A puis public sur celle de ma classe B et c'est tout?

    Qu'entends-tu par "conservant son prototype initial"?
    En utilisant la même entête?

  5. #5
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    En bref : soit ta fonction est abstraite, et elle doit porter le mot-clé abstract dans sa déclaration et pas de corps, soit elle ne l'est pas et il lui faut un corps de fonction même vide.
    Le premier cas est la solution de rawsrc et le 2e celle de ascito.

    Dans tous les cas, tu ne peux pas diminuer la visibilité d'une méthode héritée. Si elle est "protected" dans la classe mère, elle ne peut être que "protected" ou "public" dans la classe fille, pas private.

  6. #6
    Expert éminent sénior
    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
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par absot Voir le message
    Si je te suis rawsrc, il suffit que je mette abstract devant ma fonction de ma class A puis public sur celle de ma classe B et c'est tout?
    Oui, voici les cas de figures possibles :
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    <?php
     
    abstract
    class A
    {
       /**
        * Tu demandes à ce que la fonction soit obligatoirement redéfinie au moins une fois
        * dans une des classes dérivées
        */
       abstract protected function addResult($datas);
    }
     
    class B
       extends A
    {
       /**
        * la visibilité ici de la fonction peut être :
        * protected ou public mais pas private
        */
       protected function addResult($data) {
     
       }
    }
     
     
    class C
       extends A
    {
       /**
        * la visibilité ici de la fonction peut être :
        * protected ou public mais pas private
        */
       protected function addResult($data) {
     
       }
    }
     
     
    class D
       extends C
    {
       /**
        * Dans ce cas de figure tu n'es pas obligé de définir la fonction addResult
        * car elle a déjà été définie une fois dans la classe parent
        */
    }
     
    ?>
    Citation Envoyé par absot Voir le message
    Qu'entends-tu par "conservant son prototype initial"?
    En utilisant la même entête?
    oui, autrement dit tu ne peux pas ajouter un autre paramètre à la fonction dans une des classe la définissant.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class B
       extends A
    {
       /**
        * Ici le prototype initial de la fonction n'est plus respecté -> erreur
        */
       protected function addResult($data, $paramInterdit) {
     
       }
    }

  7. #7
    Expert éminent sénior
    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
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par Celira Voir le message
    soit elle ne l'est pas et il lui faut un corps de fonction même vide.
    Je ne considère pas cela comme très judicieux. Une fonction non abstraite ayant un corps vide relève à mes yeux d'une erreur de conception.

  8. #8
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    Une fonction non abstraite ayant un corps vide relève à mes yeux d'une erreur de conception.
    Effectivement, conceptuellement c'est pas terrible, même si syntaxiquement ça fonctionne (mais bon, c'est le défaut de PHP : ya des tas de choses qui fonctionnent et qu'il vaut éviter d'utiliser ).

  9. #9
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    Du coup je suis entièrement d'accord avec rawsrc, dans le sens où Les classes abstraites sont à utiliser lorsque qu'une classe mère ne doit pas être instanciée, et ou l'on veut s'assurer que les classes filles contiennent obligatoirement tels ou tels fonctions.

  10. #10
    Rédacteur

    Homme Profil pro
    Technical Lead Salesforce
    Inscrit en
    Février 2009
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Technical Lead Salesforce

    Informations forums :
    Inscription : Février 2009
    Messages : 563
    Points : 1 667
    Points
    1 667
    Par défaut
    Ok merci, je vais utiliser la méthode de rawsrc, merci, c'est résolu.

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

Discussions similaires

  1. Fatal error: Call to undefined function: () in
    Par Shyboy dans le forum Langage
    Réponses: 10
    Dernier message: 10/07/2006, 20h43
  2. [XML] [XSLT] Fatal error: Call to undefined function xslt_create()
    Par fadex dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 05/07/2006, 12h34
  3. Réponses: 3
    Dernier message: 13/05/2006, 15h48
  4. Réponses: 3
    Dernier message: 21/03/2006, 14h21
  5. Réponses: 11
    Dernier message: 08/12/2005, 16h54

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