Raoutas
Messages postés24Date d'inscriptionsamedi 24 mars 2001StatutMembreDernière intervention18 novembre 2004
-
22 févr. 2003 à 17:31
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 2013
-
5 mai 2006 à 09:22
Bonjour j'aurais besoin d'aide, je voudrai savoir comment dans un objet créer un attributs commun à toute les instances de ma classe ???
Je sais pas si je suis clair. Genre en java ça serait :
static int i=0;
Et je cherche comment le faire en delphi, devant les méthode si j'ai compris on met class. Mais devant un attribut il veut pas :
class procedure Merde(); C BON
class i:integer; C PAS BON
Raoutas
Messages postés24Date d'inscriptionsamedi 24 mars 2001StatutMembreDernière intervention18 novembre 2004 22 févr. 2003 à 17:37
Je m'excuse je viens de trouver, en fait si mon débat que je fait avec moi même intéresse quelqu'un il fallait juste mettre l'attribut juste après la déclaration de la class tout de suite après le mot clé class pas dans public privé ou protected. Je m'excuse de vous avoir déranger et bien sur je me remercie d'avoir trouver la réponse à mon problême.
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201333 23 févr. 2003 à 10:21
Voilà une discussion intéressante.
Le Pascal Objet (jusqu'à aujourd'hui et jusqu'à preuve du contraire) ne permet pas de créer de variable de classe. Celà n'aurait aucun sens : une classe est assimilée à un concept. Un concept n'est pas fait pour stocker quelque chose. Ce sont les instances de la classe, c'est à dire leur représentation matérialisée en mémoire qui aura la charge de maintenir les valeurs.
Tel que tu as déclaré monAttribut dans ton exemple, tu déclares comme s'il s'agissait d'un simple membre d'une structure de type Record.
Une approche plus orientée objet voudrait que nous utilisions le qualificatif Property :
TMonObjet = class
public
property MonAttribut : integer;
end;
A celà, plusieurs raisons :
1/- pouvoir définir finement la portée de ce membre de la classe (public, published, protected, private)
2/- en POO, le programme utilisant cette classe n'a pas à connaitre les détails de l'implémentation ni les valeurs potentiellement utilisables. Une classe doit être en mesure de protéger ses membres de toute valeur qui pourraient créer des effets de bord...
Et comme Delphi met à notre disposition (depuis Delphi 4) un outil hyper pratique sous la forme d'un élément de menu contextuel : "Compléter la classe sous le curseur" (raccourci SHIFT+CTRL+C):
TMonObjet = class
private
FMonAttribut: integer;
procedure SetMonAttribut(const Value: integer);
public
property MonAttribut : integer read FMonAttribut write SetMonAttribut;
end;
N'ayant pas précisé d'accesseur en lecture/écriture pour cette propriété, Delphi présume un accès complet et génère les noms et les squelettes de méthode dans l'unité (non reproduits ici).
Je voudrais rappeler aussi qu'il existe des conventions d'écriture (voir notamment : Delphi coding standards) et qu'il serait bon, dans le cas présent de préfixer le nom de ta classe par la lettre T. Nous avons trop souvent vu de mélanges et d'erreurs à cause d'une confusion entre la classe et l'instance de la classe à cause de celà.
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 27 avril 2006 à 12:54
Je risque peut etre de me faire mal voir par un admin mais je suis pas tout a fait daccord.
Prenons un exemple.
Soit une classe T. il est pratique de pouvoir stocker dans la classe T le nombre d'instances de cette classe, pour affecter un id par exemple.
Certes on pourrai mettre un compteur dans la classe qui instancie l'objet, mais comment faire si la classe est instanciée a partir de plusieurs classes independantes?
De plus, il me semble que les interfaces fonctionnent un peu sur ce principe en delphi.
J'ai pas trop compris leur fonctionnement mais j'ai cru comprendre qu'il fallai implementer un methode AddRef qui correspond à un compteur de references. Mais la, je connai vraiement pas beaucoup.
Merci Delphiprog si tu peu m'apporter de plus amples informations sur ma facon de penser.
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201333 2 mai 2006 à 21:28
Pas de problème Guillemouze, chacun est libre de s'exprimer et de faire part de ses convictions tant qu'elles ne sont pas religieuses, politiques ou syndicales
Cela dit, tu as écrit : "Soit une classe T. il est pratique de pouvoir stocker dans la classe T le nombre d'instances de cette classe, pour affecter un id par exemple."
A cela je répond qu'un identificateur n'a pas du tout le même rôle qu'un compteur de références.
En ce qui concerne les interfaces, si elles possèdent un compteur de référence, c'est pour détruire automatiquement un objet quand il n'est plus référencé nulle part. Pour ta connaissance, j'ajoute que tu n'es pas obligé d'implémenter les méthodes AddRef, Release et QueryInterface à partir du moment où ta classe hérite de TInterfacedObject..
Ce que demandait Raoutas, c'était de savoir s'il pouvait déclarer un membre statique comme cela existe dans d'autres langages. Hélas, dans les déclinaisons pour Win 32, Delphi ne permet pas de telles déclarations.
On peut toutefois adopter une solution qui consiste à déclarer une variable, dans la partie implémentation, du type de l'instance sur laquelle on souhaite pointer.
L'exemple typique est celui du design pattern singleton que tu peux trouver ici sur ce site et proposé par MHI.
En espérant que cela t'aura aidé à y voir plus clair.
Si tu veux voir l'utilisation des interfaces, je te conseille d'aller voir un de mes derniers codes sources et de lire le tuto qui va bien avec : Design pattern Observer avec Delphi A+
May Delphi be with you !
<hr color="#008000">
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 2 mai 2006 à 22:51
merci de ta reponse.
mais quelque chose me chagrine quand meme. Je connais vaguement le design pattern singleton, mais ce que je voudrais savoir, c si il existe un moyen d'obtenir une valeur affecté a une classe sans passer par une constante globale. Je m'explique. Imaginons que j'ai des classes et par exemple je souhaite leur affecter une chaine qui les decrit (ceci est purement un exemple et pas ce pourquoi j'en ai besoin). Je voudrais donc pouvoir recuperer cette chaine SANS AVOIR BESOIN D'UNE INSTANCE DE CETTE CLASSE. est ce que tu crois que c'est possible?
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201333 3 mai 2006 à 00:42
Dans ce cas, tu peux utiliser une méthode de classe en respectant une règle de base : une méthode de classe ne doit pas utiliser les valeurs des propriétés comme s'il s'agissait d'une instance de la classe.
Pour déclarer une méthode de classe, il suffit d'ajouter le mot clé class devant le mot clé procedure ou function.
Un exemple ?
type
TMaClasse = class
public
class function MaFonction: string;
classfunction MaFonction2: string;
end;
implementation
const
Hello = 'Good morning !';
{ TMaClasse }
classfunction TMaClasse.MaFonction: string;
begin
Result := 'Hello world !';
end ;
classfunction TMaClasse.MaFonction2: string;
begin
Result : = Hello;
end;
Ces deux fonctions ne font absolument pas appel à une propriété de la classe qui n'a d'existence que lorsqu'il y a eu instanciation.
Pour les utiliser, c'est simple :
ShowMessage(TMaclasse.MaFonction);
Pas besoin d'instancier un objet de la classe TMaClasse.
Pour plus ample information, jette un oeil dans l'oeil en ligne sur "méthodes de classes".
May Delphi be with you !
<hr color="#008000">
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 3 mai 2006 à 09:00
merci pour l'info, ca resout parfaitement mon probleme. Par contre, il n'y a pas de moyen d'avoir une valeur dynamique, c'est a dire que j'affecte une valeur au retour de cette fonction? (comme par exemple pour le pattern singleton, affecter le singleton en retour de la fonction)
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201333 4 mai 2006 à 19:33
Ben si, c'est possible. Pourquoi ça ne le serait pas ?
C'est un peu sur ce principe qu'est basé le design pattern factory :
type
TMaClass = class
public
class function GetMaClassInstance:TMaClass;
end;
implementation
{ TMaClass }
classfunction TMaClass.GetMaClassInstance: TMaClass;
begin
Result : = TMaclass.Create;
end;
L'exemple ci-dessus n'est pas forcément bien choisi puisque le résultat retourné ne fait rien de plus qu'un appel au constructeur.
Mais le principe est là. A moins que je n'ai pas bien compris le sens de ta question ?
May Delphi be with you !
<HR color=#008000>
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 5 mai 2006 à 09:22
nan je pense pas que tu ai compris le sens.
Pour ton exemple, dans tous les cas, le retour est fixé (un constructeur, une constante, ...). Ce qui m'interesserai, c'est de modifier le retour de la fonction pendant l'execution. Je t'explique mon probleme exactement.
J'ai une classe
TMyException = class(TException)
constructor create;
end;
constructor TMyException.create;
begin
showMessage(TMyAncetre.recuperer.getInfos);
end;
et ma class TMyAncetre
TMyAncetre = class
class function recuperer:TMyAncetre;
function getInfos:String;
function setRecuperable;
end;
TMyAncetre.recuperer:TMyAncetre;
begin
//La je voudrais retourner une instance mémorisée de TMyAncetre,
//qui n'est pas forcement unique, mais qui est memorisée au moment de l'execution.
//Par exemple, je voudrais retourner la derniere instance
//qui a appelé la fonction setRecuperable.
end;
Comme tu vois, a moins que je nai pas bien saisi le truc, je ne peu pas utiliser le singleton vu que j'ai plusieurs instances.
Merci de ton aide