Précédent   Forum des professionnels en informatique > PHP > Langage > Syntaxe
Syntaxe Forum d'entraide sur la syntaxe de PHP et la POO. Avant de poster -> FAQ syntaxe, Cours d'initiation et cours de POO
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 02/01/2012, 13h07   #1
Nouveau Membre du Club
 
Inscription : février 2009
Messages : 261
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 261
Points : 30
Points : 30
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 :
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:
Citation:
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?
absot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2012, 13h59   #2
Membre éclairé
 
Inscription : juin 2007
Messages : 337
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 337
Points : 393
Points : 393
alors plusieurs choses à voir

1 : écrire
Code :
protected function addResult($datas){}
en place de
Code :
 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
__________________
Conception / Dev
ascito est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 02/01/2012, 14h28   #3
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 462
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 462
Points : 2 552
Points : 2 552
Envoyer un message via Skype™ à rawsrc
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 :
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 :
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) {
      ...
      ...
   }
}
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2012, 16h18   #4
Nouveau Membre du Club
 
Inscription : février 2009
Messages : 261
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 261
Points : 30
Points : 30
Citation:
Envoyé par ascito Voir le message
alors plusieurs choses à voir

1 : écrire
Code :
protected function addResult($datas){}
en place de
Code :
 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 :
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 :
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?
absot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2012, 16h35   #5
Modératrice
 
Avatar de Celira
 
Femme
Développeuse PHP/Java
Inscription : avril 2007
Messages : 3 671
Détails du profil
Informations personnelles :
Sexe : Femme
Âge : 27
Localisation : France

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

Informations forums :
Inscription : avril 2007
Messages : 3 671
Points : 5 404
Points : 5 404
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.
__________________
Modératrice PHP
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)

Pour afficher votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur)
Celira est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2012, 16h43   #6
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 462
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 462
Points : 2 552
Points : 2 552
Envoyer un message via Skype™ à rawsrc
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 :
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 :
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) {
 
   }
}
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2012, 16h47   #7
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 462
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 462
Points : 2 552
Points : 2 552
Envoyer un message via Skype™ à rawsrc
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.
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2012, 17h02   #8
Modératrice
 
Avatar de Celira
 
Femme
Développeuse PHP/Java
Inscription : avril 2007
Messages : 3 671
Détails du profil
Informations personnelles :
Sexe : Femme
Âge : 27
Localisation : France

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

Informations forums :
Inscription : avril 2007
Messages : 3 671
Points : 5 404
Points : 5 404
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 ).
__________________
Modératrice PHP
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)

Pour afficher votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur)
Celira est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2012, 19h26   #9
Membre éclairé
 
Inscription : juin 2007
Messages : 337
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 337
Points : 393
Points : 393
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.
__________________
Conception / Dev
ascito est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2012, 20h48   #10
Nouveau Membre du Club
 
Inscription : février 2009
Messages : 261
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 261
Points : 30
Points : 30
Ok merci, je vais utiliser la méthode de rawsrc, merci, c'est résolu.
absot est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 03h37.


 
 
 
 
Partenaires

Hébergement Web