Bonjour, voilà je suis entrain d'étudier les classes abstract, mais je rencontre un probème, ou je suis un peu bloqué, j'ai regardé un peu sur les FAQ, mais je n'est pas trouvé la solution vraiment à mon problème, qui est le suivant :
J'ai trois classes : une classes abstract et deux classe qui hérite de la classe abstract
- abstract class FonctionNommee
- class CosMoinsNommee
- class ImprimerFonction
Voici la composition de ces classes en gros
// Classe FonctionNommee
abstract class FonctionNommee
{
String nomFonction;abstract double calculer(double x);
void imprimer() {.......Corps du code.....;}
}// Classe CosMoinsNommee
class CosMoinsNommee
{
String nomFonction
//Constructeur
CosMoinsNomme(String nomFonction){............}// Méthode redéfinit
double calculer(double x) {.......... Corps du code ...........}
}class ImprimerFonction
{
ImprimerFonction();
double calculer(double x) {return 0;}
void lister();
}
Donc en fait, j'ai compilé la classes FonctionNomme et la CosMoinsNommee, pas de problème jusque là
Par contre lorsque que j'ai compilé la clase ImprimerFonction, le problème c'est posé.
D'après la documentation que j'ai consulté quand on utilise une classe abstract pour toutes les méthodes abstract de cette classe doivent être redédéfinit dans les sous-classes de la classes abstract.
Et donc cela signifie que dans cette exemple qu'il faut absolument que je redéfinisse la méthode calculer() à la fois dans la classe CosMoinsNomme et dans la classe ImprimerFonction.
C'est là le problème, je souhaiterai redéfinir cette méthode uniquement dans la classe CosMoinsNomme car c'est uniquement dans cette classe que je rédéfinit calculer.
Si je déclare uniquement la fonction calculer dans la classe ImprimerFonction en abstract, il me met se message :
Math/ImprimerFonction.java:4: Math.ImprimerFonction is not abstract and does not
override abstract method calculer(double) in Math.ImprimerFonction
class ImprimerFonction extends FonctionNommee
^
1 error
Cela signifie que ma classe ImprimerFonction n'est pas abstract, donc aucune méthode de cette classe ne peut être mis en abstract.
si je met le corps met rien à l'intérieur du corps de cette fonction, il me dit que j'ai oublié le return car la signature de la méthode calculer est la suivante :
double calculer(double x)
Donc ce que j'ai fait pour contourner le problème j'ai mis return 0 dans le corps de la fonction, est ce qu'il aurait un autre moyen pour résoudre ce problème, je souhaiterai que le compilateur ne prenne en compte la rédéfinition de la méthode calculer dans la classe ImprimerFonction, avec des anotations par exemple, je pense que ça doit être possible, je pensais que ça allait marché avec @override, mais j'ai pas bien compris le principe peut être aussi que ça dépend des version JDK, Moi j'ai la version 6.0....
j'espère que j'ai été claire dans l'explication, n'hésiter pas à me demander des précisions.
Désolé pour la longueur du message.
Merci pour votre aide
dav79
Non... ;)
Mais on va essayer de t'aider quand même :)
Oui.
Non
Ou du moins pas forcément. Si tu as
class ImprimerFonction extends FonctionNommee
C'est oui
Mais si tu as
class ImprimerFonction extends CosMoinsNommee
C'est non car dans ce cas ImprimerFonction hérite de l'implémentation de calculer dans CosMoinsNommeee Et tel que tu poses ton problème c'est cee que tu veux.
Donc pour résoudre pas besoin d'annotions ou autres trucs fumeux. Simplement tu dérives de CoisMoinsNomme au lieu FonctionNommee
Maintenant si tu me le permets, le simple fait de dériver pour écrire ImprimerFonction me semble une faute de programmation. Enfin pas une faute stricto sensu, mais un viol des bons principes des Design Pattern. Bon si c'est ce qu'on t'a demandé de faire, on va pas discuter.
Sinon ImprimerFonction ne devrait pas dériver de quoi que ce soit, mais être une classe qui implémente une fonctionnalité d'impression, et alors CosMoinsNommee doit avoir comme membre une instance de ImprimerFonction et la méthode imprimer de CosMoinsNommee invoquera alors les méthodes de ImprimerFonction.
Gros avantage, ImprimerFonction va servir tout le temps, c'est ce que appelle un découplage. Sinon, le jour où tu écris une classe CosPlusNommee tu vas devoir encore dériver pour pourvoir l'imprimer.
J'espère que j'ai été cair dans l'explication. N'hésite pas à me demander des précisions ;) :)
si tu veux ne pas redefinir ta methode calculer, tu met la class ImprimerFonction comme abstract.
A+
Mourad :)
Pourquoi pas. Mais j'avoue que dans le contexte du problème, je ne saisi pas bien l'intérêt pratique. Si la classe ImprimerFonction est abstraite, on ne peut pas imprimer avec...
Est-ce que j'ai loupé un épisode ?
a moins que le model n'est pas encore au point ?
Ca c'est sûr :)
D'ailleurs à l'attention de dav79:
De même qu'il ne devrait jamais y avoir de code dupliqué dans un programme, il ne devrait jamais avoir de "fausses implémentations" comme celle du return 0
En fait, comme le dit m.zamoun, le modèle n'est pas au point. Il ne devrait pas y avoir de méthode "calculer" dans la classe ImprimerFonction, mais seulement dans CosMoinsNommee. Ce qui est dire autrement la même chose que ce que j'ai voulu dire avec mon histoire d'instance de ImprimerFonction membre de CosMoinsNommee. Mais j'avais oublié de bien lpréciser que dans ce cas la classe ImprimerFonction n'a pas (et ne doit pas avoir) de méthode "calculer". Ou, pour te résumer ça en une phrase, ImprimerFonction ne devrait dériver ni de FonctionNommee ni de CosMoinsNomme. Il n'y a aucune raison de dériver là.
Je pense que j'était claire dans mon explication,
Le problème n'est pas de savoir si l'implémentation est judicieuse ou non, c'est juste des tests, je suis les ennoncées de l'exercice, c'est pas moi qu'a fait l'analyse
Je rappel rapidement mon souci. J'ai trois classes :
- 1 class abstract FonctionNommee qui deux méthodes :
-- abstract calculer()
-- void imprimer(double x) {...................}
- 1 class CosMoinsNommee() : sous-class de FonctionNommee
-- le constructeur
-- méthode redéfinit calculer(double x) {...................}
- 1 class ImprimerFonction sous-classe FonctionNommee a deux méthodes
--- Constructeur
--- void lister(){................}
-- calculer // Car je suis obligé de redéfinir cette méhode,
La classes ImprimerFonction ne peut être déclaré en abstract car la méthode lister() n'est pas une méthode abstract, c'est bien là le problème.
Au départ je n'avais pas mis la méthode calculer dans la classe ImprimerFonction, mais le compilateur ne l'accepte pas, puisque que la classe ImprimerFonction est une sous-classe de la classe FonctionNommee, on doit obligatoirement redéfinir les méthodes abstract dans les classes filles. Et donc ici je doit redéfinir calculer() dans les sous-classes CosMoinsNomme et ImprimerFonction.
Moi je souhaiterai redéfinir calculer dans CosMoinsNomme, comment faire pour faire comprendre au compilateur qu'il n'est pas nécessaire de rédifinir calculer dans la class ImprimerFonction, tout tenant compte que la classe ImprimerFonction doit être une sous-classe de class FonctionNommee.
Est ce que maintenant c'est plus claire.
C'est pourquoi j'ai parlé d'annotation comme par exemple @override, je crois que cette instruction veut dire que le compilateur ne tient pas compte de la redéfinition de la méthode de la classe parent.
Est ce que vous avez cerné mon problème maintenant, est ce quelqu'un aurait une solution, naturellement je pense que oui, ça doit être un problème classic de débutant que j'expose, j'attends vous réactions.
Je vous remercie par avance,
dav79
C'était clair et on avait compris.
Par contre toi si tu voulais prendre le temps de comprendre les réponses....
Oui oui on avait deviné que c'était un exercice. Si tu lis ma première réponse j'y fais allusion.
Donc NON, comme je te l'ai dit dans ma première réponse, tu n'es pas obligé de redéfinir cette méthode
Alors on a cerné depuis le début , on a une solution, et on te la donne pour la deuxième fois et on attend que le débutant ait la réaction de lire ce qu'on lui dit.
donc tu écris
ImprimerFonction extends CosMoinsNommee
comme calculer est implémentée dans CosMoinsNommee, ImprimerFonction en hérite et donc tu n'as pas besoin de l'implémenter à nouveau.
Et comme CosMoinsNommee dérive de FonctionNommee, AUTOMATIQUEMENT ImprimerFonction dérive de FonctionNommee comme on te le demande dans l'énoncé.
voilà voilà :twisted: :twisted:
Je te l'ai dit dès le début, et tout le reste était une discussion sur le caractère très mauvais de l'énoncé. Mais bon là je ne vais pas répéter hein... :twisted:
Ah un dernier mot.
Je ne trouve pas normal que dans FonctionNomme il y ait une méthode "imprimer" et que dans ImprimerFonction on ait "lister" et non pas "imprimer" :lol: Dans une classe qui doit s'appeler ImprimerFonction et qui doit dériver de FonctionNomme, laquelle comporte une méthode imprimer, on s'attend légitimement à trouver une redéfinition de imprimer dans ImprimerFonction, tu ne crois pas :?: :lol:
Si tu as tout à fait raison fredericmazue concernant ta dernière remarque, l'organisation des classes n'est pas logique
En fait je viens de m'aperçevoir que j'ai fait une erreur dans la lecture du sujet.
J'était perçoidé que ImprimerFonction était une sous-classe de FonctionNommee, c'est à dire avec cette déclaration.
class ImprimerFonction extends FonctionNommee, mais le sujet ne le précise pas explicitement, voici un extrait :
2/ Ecrire une classe nommée ImprimerFonction qui est destinée à lister les valeurs d'une fonction depuis une borne inférieur jusqu'à une borne supérieure avec un pas donné. La classe comportera donc un champ FonctionNommee qui est la fonction à étudier, un champ définissant la borne inférieur, un champ définissant la borne supérieure et un champ définissant le pas. Elle contiendra en plus un constructeur, une méthode appelée lister( ) qui permet d'imprimer les valeurs qu'on veut et la fonction main ( ) dans laquelle on fera une application avec un objet CosMoinsNommee.
Donc tu as raison, je vais déclaré ImprimerFonction en sous-classe de CosMoinsNommee, comme ça le problème sera reglé.
Désolé aussi, j'ai peut être un peu lu vos réponses trop rapidement, je m'en excuse.
En tout cas merci pour l'aide que vous m'avez apporté.
dav79
Hum, je crois que tu es encore dans l'erreur...
Voilà qui me rassure quant à la valeur du sujet :)
Non :!:
Si tu fais une sous classe *ton* problème tel que tu as dit l'avoir rencontré dans ton premier message sera réglé. Mais si tu lis bien ton énoncé, je ne pense pas que c'est ce qu'il faut faire.
Je t'avais parlé, pour une bonne conception, d'une classe "Fonction" qui détenait un membre ImprimerFonction pour imprimer des résultats.
Je crois que l'énoncé te demande la même chose, mais dans l'autre sens ce qui est correct aussi. C'est à dire une classe ImprimerFonction (qui dérive de rien de particulier donc) et qui a un membre "FonctionAImprimer" de type FonctionNommee et qui pourrait être par exemple CosMoinsNommee. Et ImprimeFonction appelle la fonction calcule de la classe qui dérive de FonctionNommee (par exemple CosMoinsNommee) pour imprimer.
En terme de programmation cette façon de faire s'appelle le Desing Pattern Strategy.
Un peu de (pseudo) code pour te fixer les idée:
C'est tout simple :) Kapito ?