PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 2025 → Héritage Classe et Globales
Héritage Classe et Globales
Iniciado por yogan, 03,sep. 2019 15:15 - 3 respuestas
Miembro registrado
16 mensajes
Publicado el 03,septiembre 2019 - 15:15
Bonjour,

Pour faire bref, je cherche à avoir un membre défini dans une classe parent qui devienne globale dans la classe qui en hérite, mais qui reste accessible à la classe parent.

Comme c'est pas forcément clair, voilà un exemple :

Je souhaiterai faire un système de classe comme suit ...

UnAnimal est une Classe
m_nID est un entier
GLOBAL
m_sNomAnimal est une chaîne = "Inconnu"
FIN

Constructeur(nID est un entier)
m_nID = nID
FIN

Procedure Caresser()
Info(m_sNomAnimal + " " + m_nID + " a été caressé !")
FIN


UnChien est une Classe
hérite de UnAnimal
GLOBAL
m_sNomAnimal = "Chien"
FIN

Procedure Aboyer()
Info(m_sNomAnimal + " " + m_nID + " aboie !")
FIN


UnChat est une Classe
hérite de UnAnimal
GLOBAL
m_sNomAnimal = "Chat"
FIN

Procedure Miauler()
Info(m_sNomAnimal + " " + m_nID + " miaule !")
FIN


Évidemment, la syntaxe et fausse et ceux parmi vous qui gèrent bien les classes voient sans doute déjà le problème avec mon utilisation de GLOBAL :

Je voudrais pouvoir faire :

Info(UnChien.m_sNomAnimal) // -> info "Chien"
clUnChien est UnChien(1)
clUnChien.Aboie() // -> info "Chien 1 aboie !"
clUnChien.Caresser() // -> info "Chien 1 est caressé !"

Info(UnChat.m_sNomAnimal) // -> info "Chat"
clUnChat est UnChat(1)
clUnChat.Miaule() // -> info "Chat 1 miaule !"
clUnChat.Caresser() // -> info "Chat 1 est caressé !"


Or comme j'ai déclaré m_sNomAnimal en global, j'obtiens UnChien.m_sNomAnimal = "Chat" car le membre est globale à UnAnimal (au lieu d'UnChat) et a été modifiée quand j'ai instancié clUnChat

Comment faire pour qu'un membre d'une classe ne soit GLOBAL *que* pour les classes qui en héritent en restant accessible à cette classe parent ? Et donc pouvoir avoir des globales indépendantes pour chaque suivant la classe qui en hérite :

Trace(UnChien.m_sNomAnimal) // "Chien"
Trace(UnChat.m_sNomAnimal) // "Chat"
Trace(UnAnimal.m_sNomAnimal) // "Inconnu"


Je soupçonne qu'il faille utiliser du virtuel ou abstrait, mais ce n'est pas encore trop clair pour moi.

Merci d'avance !
Mensaje modificado, 03,septiembre 2019 - 15:19
Miembro registrado
953 mensajes
Publicado el 04,septiembre 2019 - 17:30
bonjour Simon,

le mot clé PROTEGE permet de déclarer un membre qui ne sera accessible que dans la classe ou bien dans les classes qui en hérite.

Je ferai un truc du genre :

votre classe Animal, avec une propriété PROTEGEE en lecture / écriture et une propriété Publique en lecture seulement pour votre NomAnimal

UnAnimal est une Classe
m_nID est un entier
PROTÉGÉ
m_sNomAnimal est une chaîne
FIN

Constructeur(nID est un entier)
:m_nID = nID
:_MonNom="Inconnu"
FIN

// Récupération de la propriété _MonNom
Procedure PROTEGEE _MonNom()
RENVOYER m_sNomAnimal

// Affectation de la propriété _MonNom
Procedure PROTEGEE _MonNom(Valeur)
:m_sNomAnimal =valeur

// Récupération de la propriété MonNom
Procedure PUBLIQUE MonNom()
RENVOYER m_sNomAnimal



UnChat est une Classe
hérite de UnAnimal
FIN

// Constructeur
Constructeur(nID est un entier)

Constructeur c_Animal(nID) // Appel explicitement le constructeur de la classe héritée
:_MonNom="Chat" // On redéfinie le nom de l'animal




UnChien est une Classe
hérite de UnAnimal
FIN

// Constructeur
Constructeur(nID est un entier)

Constructeur c_Animal(nID) // Appel explicitement le constructeur de la classe héritée
:_MonNom="Chien" // On redéfinie le nom de l'animal
Miembro registrado
16 mensajes
Publicado el 12,septiembre 2019 - 16:50
(Re)Bonjour Christophe

Je revenais sur ce post par curiosité et je vois que la réponse que je vous avait faite a disparu (où aurais-je oublié de la poster ?).

Bref, la méthode que vous indiquez est plus ou moins ce sur quoi nous nous sommes rabattus : faire remonter des paramètres à la classe parent, mais c'est pas génial :

- Si on utilise une méthode comme dans votre exemple, on ne peut pas la faire globale, car sNomAnimal de la classe parent n'est pas globale

- Du coup, pour obtenir le nom de l'animal, on ne peut pas utiliser sa classe, mais on doit passer par une instance de classe : UnChien.m_sNonAnimal devient >> clUnChien est UnChien(); clUnChien.NomAnimal

- De même, on ne peut pas définir une méthode globale "ListerTous" dans UnAnimal pour l'utiliser directement depuis UnChien (UnChien.ListerTous pour avoir tous les "chiens") car la méthode étant globale, elle ne pourra accéder au nom d'animal "chien" qui est un membre d'instance.
Mensaje modificado, 12,septiembre 2019 - 16:51
Miembro registrado
1.173 mensajes
Publicado el 10,abril 2020 - 15:04
Bonjour,

Il semble que le concept des classes soit un peu flou dans votre esprit ;-)

Pour manipuler une liste d'objet d'une classe, il faut
1 - soit créer une classe avec comme donnée membre un tableau de cChien, un tableau de cChat...
2 - soit utiliser un tableau de d'objet dynamique dans une classe...
3---

Ce type de liste doit être considéré comme une "collection" d'objets.

L'objectif final étant de manipuler un chien, ou un chat.... il est normal de ne pas utiliser la classe animal (qui est finalement abstraite).

La solution de Christophe est la bonne, il vous manque juste un tableau d'objets de ces classes.

--
Thierry TILLIER
Développeur Windev-Webdev
Formation Windev (initiation aux classes) : https://coursdinfo.teachable.com/p/windev-programmer-avec-les-classes
Formateur bureautique (individualisation) : https://coursdinfo.net