je n'arrive pas à faire un héritage entre une classe mère Monstre et les classes filles Zombi,Troll,Orc etc.
c'est au moment d' instancier l'objet mon_zombi que ça plante, j'ai tout essayé et j'ai obtenu l'arc en ciel des erreurs possible : typeerror , attributeerror, __init__() missing 4 arguments etc. Même en s'inspirant d'exemples du net , je ne comprend pas !
Il s'agit d'un code test devant servir à démouler vite fait mon premier zombi, il est prévu de changer mais comme ça bloque déjà...
class Monstre():
def __init__(self,pos_y,pos_x,race,pv):
self.__pos_y = pos_y
self.__pos_x = pos_x
self.__race = race
self.__pv = pv
def spawn(self):
screen.addch(20,40,'Z')
# il faudra utiliser plus tard un dico_symbol_monstre comme intermédiaire a la place de "Z" directement (zombi)
def die(self):
screen.delch(self.__pos_y,self.__pos_x)
chr(screen.inch(self.__pos_y,self.__pos_x))==' '
screen.refresh
class Zombi(Monstre):
# def __init__(self,pos_y,pos_x,race,pv):????????????
def __init__(self):
Monstre.__init__(self,self.pos_y,self.pos_x,self.race,self.pv)
#Monstre.__init__(self,20,40,'race_Zombi',95) ???????????
mon_zombi = Zombi()
C'est la première fois que je me frotte à l'héritage
- Edité par buffalo974 27 septembre 2014 à 19:14:38
De manière générale, si tu veux construire un objet sur le modèle de la classe mère, fait super().__init__(arguments), super est une fonction qui te donne au sein d'une classe fille la classe mère. Sinon je pense que le problème vient du fait que tu appelles Monstre.__init__ avec un argument de trop et que tu lui passe en argument des attributs inexistants. Essaie donc de remplacer ta ligne 28 par:
super().__init__(20, 40, 'race_Zombi', 95)
Edit: C'est HS mais "Zombi" s'écrit "Zombie" .
Edit 2: Je note quand même que les '__' avant tes attributs dans Monstre.__init__ sont contraire aux règles de la POO pythonienne car, en Python, les attributs sont publics donc pas d'encapsulation à proprement parler. Et en plus ça sert pas à grand chose car un utilisateur peut très bien y accéder en tapant:
Et n'oublie de placer les attributs quand tu créé l'instance:
mon_zombi = Zombi(0, 0, "Zombie", 240)
REMARQUE: À moins que tu veuille ajouter/surcharger des méthodes/attributs (que tu n'aurait pas montré dans ce morceau de code), l'héritage dans le cas que tu présente n'a pas d'intérêt. Tu pourrai directement faire:
Voici deux sources d'inspiration de deux auteurs réputés :
# http://fr.openclassrooms.com/forum/sujet/un-jeu-d-echec-en-console-77316
class Piece(object):
"""
Interface commune à toutes les pièces.
Ne s'utilise pas directement.
"""
def __init__(self, echiquier, couleur, symbole):
"""
Construit une pièce.
echiquier : echiquier sur lequel se trouve la pièce
couleur : NOIR ou BLANC.
symbole : caractère symbolisant la pièce.
"""
self.__echiquier = echiquier
self.__couleur = couleur
self.__symbole = symbole
(...)
###############################################################################
# classes dérivées de Piece
class Tour(Piece):
def __init__(self, echiquier, couleur):
Piece.__init__(self, echiquier, couleur, SYMBOLE_TOUR)
class Pion(Piece):
def __init__(self, echiquier, couleur):
Piece.__init__(self, echiquier, couleur, SYMBOLE_PION)
(...)
--------------------------------------------------------------------------------
# http://sametmax.com/le-guide-ultime-et-definitif-sur-la-programmation-orientee-objet-en-python-a-lusage-des-debutants-qui-sont-rassures-par-les-textes-detailles-qui-prennent-le-temps-de-tout-expliquer-partie-5/
class Arme(object):
def __init__(self, nom, degat):
self.nom = nom
self.degat = degat
def attaque(self, cible): # on retire les degâts de l'épee des points de vie
cible.vie -= self.degat
class Protection(object):
def __init__(self, nom, armure):
self.nom = nom
self.armure = armure
def defend(self, degat): # on diminue les degâts, voire on les annule
degat = degat - self.armure
if degat < 0:
return 0
return degat
>>> epee = Arme('Epée Mana', degat=999)
>>> casque = Protection('Casque de Balduran', armure=1)
(...)
class ProtectionOffensive(Arme, Protection):
def __init__(self, nom, degat, armure):
Arme.__init__(self, nom, degat) # appelle le __init__ de arme
Protection.__init__(self, nom, armure) # appelle le __init de protection
# comme on a appelé les deux __init__, on va avoir les attributs
# settés dans les deux __init__ attachés à cette classe
>>> bouclier = ProtectionOffensive('Bouclier du dragon', degat=10, armure=100)
>>> bouclier.degat
10
>>> bouclier.armure
100
>>> bouclier.defend(10)
0
En fait , je voudrai disposer d'un réservoir de monstres ( liste, ou dico, ou liste couplée avec un dico; voire une bdd sqlite sur une version top finale). Cependant les monstres ne doivent pas apparaître tout d'un coup au démarrage, mais de façon "exponentielle" de façon à mettre une pression progressive et que le joueur ne s'attarde pas trop dans un niveau.
La classe Monstre dirait que chaque creature possède une jauge de vie,des points d'attaques etc. et définirait les méthodes taper() , fuir()...
Puis les classes filles Zombi,Troll,Vampire etc. donneraient le montant précis de chaque attribut , ainsi que des méthodes uniques telle que
hypnotiser() pour le vampire : fige (x,y) du joueur pendant 2 tours par exemple.
Qu'est-ce que tu entends pas "réservoir de monstres"? Si c'est de créer à l'avance un certain nombre de zombies, vampires, etc... je dirai que ce n'est pas la meilleure façon de faire.
Bon, ça va dépendre énormément de comment tu gère ton projet. Tu pourrais par exemple mettre les infos pour les monstres de base en valeur par défaut de tes classes:
Certes des personnes réputées utilisent ce style de programmation, car en général ils viennent d'un langage comme le C++ ou le java.
Mais des auteurs comme Van Rossum ou Martelli quand à eux ne sont pas pour... à moins de les utiliser pour éviter les collisions de noms de variables entre les classes filles et leur classe mère. C'est pas pour rien que par mon exemple on peut en faisant un effort y accéder, car en modifiant ce nom de variable, on évite cette collision. En gros cette variable reste privée mais est protégée de toute modification car en réalité elle n'est pas nommée comme on le croit.
Bref la variable privée est conseillée que pour les frustrés de langage tel le C++/Java/... où les variables privées sont indispensables. En python ce n'est pas le cas, on laisse totale liberté et responsabilité au programmeur.
Ensuite pour ton problème de zombi, en fait
class Zombi(Monstre):
def __init__(self):
Monstre.__init__(self,20,40,'race_Zombi',95)
</pre>
Note: en Python 3 tu peux te passer des arguments passés à super, mais il est préférable de les spécifier tout de même pour que le code soit portable.
Sinon je ne connaît pas les avantages de super, cette fonction renvoie juste l'objet self en tant qu'instance de sa classe mère.
Edit: je viens de trouver ça: http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.