Le site http://www.poo.c.la proposait une introduction à la programmation orientée objet (POO) dès 2004, à un moment où l’on en parlait peu dans WinDev. Il a certainement aidé bon nombre de développeurs mais a récemment quitté internet. Donc pour se souvenir de cette période et lire ces articles qui restent pertinents, voici le contenu qu’il a été possible de récupérer. Merci à son contributeur.
Les différents types de programmation
Démystification ou la POO pour les nuls
Certains développeurs aiment dire qu’ils développent en objet pour dirent qu’ils développent mieux que les autres. Ce n’est pas forcément vrai. En programmation objet comme dans tout autre méthode de programmation, on peut bien ou mal développer.
Programmer en objet n’est pas plus difficile que les autres types de programmation. Il y a certaines règles à connaître, et surtout une syntaxe spécifique (syntaxe qui dépend du langage).
La programmation objet est très proche de la programmation procédurales avec la notion de collection de procédures proposée par PC SOFT.
Note : Dans un premier temps il est fait abstraction des notions avancées de la POO (héritage, surcharge, dérivation….)
La principale différence est que pour utiliser les méthodes d’une classe il faut au préalable déclarer un objet (une variable) basé sur la classe (le type). Pourquoi cette contrainte ? Cela permet d’utiliser en même temps plusieurs procédures qui manipulent des variables globales sans qu’elles n’interagissent les unes avec les autres.
Exemple avancé reprenant les différentes syntaxes à utiliser en programmation objet en W-Langage.
Attention, les exemples sont anciens et la syntaxe a été allégée. Plus besoin d’un : devant les noms et le : entre classe et méthode peut être remplacé par un point.
//*********** Exemple de code de déclaration d'une classe en W-Langage //Constantes de la classe //Remarque : on est avant "ClasseExemple est une classe" CONSTANT //Syntaxe générale : =Valeur CST1CLASSEEX= 10 CST2CLASSEEX= "BONJOUR" FIN //Structure utilisée par la classe //Remarque : on est avant "ClasseExemple est une classe" StructurePourClasse est une structure MembreStructureClasse est un entier //Autres membres de la structure FIN //Membres de la classe (ClasseExemple représente le nom de la classe) ClasseExemple est une classe //Uniquement dans le cas où la classe hérite d'une autre classe //Syntaxe générale : hérite de //A mettre impérativement au début avant les membres de la classe hérite de ClasseAncêtre //On peut noter qu'il est également possible d'utiliser cette autre syntaxe : //un objet ClasseAncêtre(ParamConstructeurAncêtre) //Je conseille toutefois la première syntaxe //Membres globaux (commun à tous les objets bases sur cette classe dans le projet) GLOBAL MembreGlobal est une chaîne //Membres locaux (propre à chaque objet, à chaque instanciation de la classe) : Par défaut LOCAL //Membres privés (utilisables uniquement dans la classe) PRIVÉ //Uniquement dans le cas où la classe utilise une autre classe MembreObjet est un objet AutreClasse //Membres privés de la classe MembreClasse est une chaîne //Membres publics (utilisables dans la classe et en dehors de la classe) : Par défaut PUBLIC MembreClasseBaséSurStructure est un StructurePourClasse //Membres publics constant (utilisables en L/E dans la classe et en lecture seule en dehors de la classe) PUBLIC CONSTANT MembreConstantClasse est un StructurePourClasse //Membres protégés (accès autorisé depuis un code de la classe ou un code d'une classe dérivée) PROTÉGÉ MembreProtege est un entier FIN //**************** Exemple de constructeur de classe //ici constructeur qui attend 2 paramètres PROCEDURE Constructeur(Param1,Param2) //appel du constructeur de la classe ancêtre (si nécessaire) //A mettre impérativement au début avant les autres initialisations Ancêtre:Constructeur(Param1) //OU //Constructeur Ancêtre(Param1) //OU //En cas d'héritage multiple, ou pou être plus explicite on peut nommer la classe ancêtre : //ClasseAncêtre:Constructeur(Param1) //OU //Constructeur ClasseAncêtre(Param1) //En cas d'héritage multiple, ou pou être plus explicite on peut nommer la classe ancêtre : //ClasseAncêtre: Constructeur(Param1) //appel des constructeurs des membres qui sont eux-mêmes des objets (si nécessaire) :MembreObjet:Constructeur(Param2) //initialisation des membres (si nécessaire) //A part dans la déclaration de la classe, pour manipuler les membres de la classe, il faut les préfixer de ":" (de la même façon pour les méthodes) :MembreClasse = "INIT" //Ici affectation d'un membre basé sur une structure :MembreClasseBaséSurStructure:MembreStructureClasse = 10 //**************** Exemple de méthode de classe (déclaration et manipulation des différents éléments de la classe dans le code) PROCEDURE PROTÉGÉ VIRTUELLE MéthodeExemple(Parametre1,Parametre2="") //PROTEGE: car la méthode n'est accessible que depuis les autres méthodes de la classe et les classes dérivées. //Il faut mettre PRIVE pour pouvoir appeler cette méthode que depuis la classe elle-même. Et il ne faut rien mettre (ou PUBLIC) pou pourvoir l'appeler en dehors de la classe //Il est possible de mettre GLOBAL (entre PROTEGE et VIRTUELLE) pour indiquer que cette méthode peut être appelée sans instanciation d'objet (juste avec la classe) //VIRTUELLE indique que si cette méthode est redéfinie dans une classe dérivée, c'est la méthode de la classe dérivée qui sera appelée même depuis cette classe //** Ici exemple d'appel de la méthode de même nom de la classe ancêtre (méthode qui existe donc dans la classe en cours est dans la classe ancêtre) //Il faut ajouter le mot "Ancêtre" (ou le nom de la classe en cas d'héritage multiple) devant le nom de la méthode Ancêtre:MéthodeExemple(Parametre1) // et donc l'autre possibilité en cas d'héritage multiple : //ClasseAncêtre:MéthodeExemple(Parametre1) //Exemple d'utilisation d'un membre global : il faut préfixer de "::" ( de la même façon pour une méthode globale) ::MembreGlobal=10 //Exemple d'utilisation d'une constante de la classe : il faut préfixer de "::" ( les constantes sont des membres globaux non modifiables) Info(::CST1CLASSEEX) //**************** Exemple de code (hors de la classe elle-même), qui utilise une classe //Déclaration de l'objet (ici on passe 2 paramètres au constructeur) ObjPerso est un objet ClasseExemple(1,2) // si le constructeur n'a pas de paramètre, il faut écrire : //ObjPerso est un objet ClasseExemple //Utilisation d'une structure de la classe MaStructure est un ClasseExemple::StructurePourClasse //Appel d'une méthode ObjPerso:MéthodePublic("Mon Paramètre") //Appel d'une méthode globale : il faut utiliser le nom de la classe (et pas celui d'un objet), et il faut préfixer le nom de la méthode de "::" ClasseExemple::MéthodeGlobale("Autre Paramètre") //Appel d'une constante de la classe : il faut utiliser le nom de la classe (et pas celui d'un objet), et il faut préfixer le nom de la constante de "::" Info(ClasseExemple::CST1CLASSEEX)
Exemple de classe utilitaire
Voici une première classe utilitaire.
Elle permet de modifier le comportement des champs séparateurs (splitters).
Détail :
Lorsqu’il y a plusieurs champs séparateur dans une même fenêtre, en exécution ceux-ci peuvent se « croiser » et donner des affichages non prévus. Lorsqu’ils ne se croisent pas. De la même façon pour déplacer un séparateur compris entre deux autres séparateur, il est nécessaires de modifier au préalable l’emplacement du séparateur se trouvant au dessus ou au dessous.
Et une fenêtre de test qui utilise cette classe.
Fenêtre avec 3 séparateurs horizontaux et 3 séparateurs verticaux.
Vous pourrez voir que les déplacements des différents séparateurs « poussent » les autres séparateurs.