Quel différence entre une methode de classe et d'instance ?
zenx
Membre
Bonjour les ami(e)s !
J'aimerais bien comprendre simplement la diffférence entre une methode de classe et une methode d'instance, le contexte dans lequel on utilise une methode de classe plutôt qu'une methode d'instance, et peut être aussi un exemple de chaque qui illustrerait l'emploi des deux types de methode.
D'avance, un grand merci !
P.S.: Cela s'applique t il aussi aux variables (variables de classe et d'instance ?!)
J'aimerais bien comprendre simplement la diffférence entre une methode de classe et une methode d'instance, le contexte dans lequel on utilise une methode de classe plutôt qu'une methode d'instance, et peut être aussi un exemple de chaque qui illustrerait l'emploi des deux types de methode.
D'avance, un grand merci !
P.S.: Cela s'applique t il aussi aux variables (variables de classe et d'instance ?!)
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Le quelque chose, c'est soit un objet (on parle alors d'instance de classe), soit une classe.
Si la méthode est une méthode d'instance, c'est qu'elle va s'appliquer sur un objet existant.
Si la méthode est une méthode de classe, elle s'appliquera à une classe.
L'exemple concret est la fameuse ligne de création d'un objet :
[tt]unObjet=[[NSObject alloc] init];[/tt]
Dans cette ligne, il y a 2 méthodes : alloc et init.
La première méthode alloc est une méthode de classe (la méthode est appliquée à NSObject qui est bien le nom d'une classe). Cette méthode demande à la classe NSObject de créer un objet. Lorsque l'objet est correctement créé, alloc retourne son identifiant.
La seconde méthode init est une méthode d'instance, car elle s'applique à un objet (dans l'exemple précédent, l'objet est celui retourné par alloc). Cette méthode demande à l'objet de s'initialiser correctement.
.
Méthode d'instance : l'objet doit forcément être instancié.
Je crois qu'on parle également de méthode virtuelle pour les méthodes de classe mais la, je m'avance peut être un peu.
Par exemple, les constructeurs sont par définition des méthodes de classe (l'objet n'existe pas encore et le constructeur va le créer).
Hope this help.
[ah ben j'arrive un peu tard...]
C'est un raccourci un peu rapide...
La méthode de classe est appellé sur l'objet Classe lui-même (et donc, effectivement, n'utilise pas d'objet instancié).
.
une méthode de classe c'est souvent pour créer ou récupérer une instance. Par exemple alloc est une méthode de classe, tu l'appliques sur une classe comme par exemple [NSString alloc], qui te renverra un objet de type NSString, et surtout pas sur une variable genre [mastring alloc] (*). Un autre exemple de méthode de classe c'est pour récupérer une "sharedInstance" genre [NSNotificationCenter defaultCenter] pour récupérer un objet, qui est ici le centre de notification par défaut.
Une méthode d'instance c'est une méthode qui s'applique à un objet, par exemple il est exclus d'écrire [NSString init] car init est une méthode d'instance, donc qui doit s'appliquer sur un objet et non sur une classe comme ici la classe NSString. Y'a des chances que ce genre de ligne te génère une erreur de compilation d'ailleurs, j'imagine.
Et surtout pour rajouter qqch qui n'a pas encore été dit, pour les variables oui c'est pareil. Une variable d'instance est une variable qui est propre à un objet : c'est à dire que pour chaque objet créé la variable peut prendre une valeur différente d'un objet à un autre. Une variable de classe est une variable dont la valeur est commune à tous les objets de cette classe, et qui aura la même valeur d'un objet à un autre.
Par exemple j'imagine que dans la classe NSNotificationCenter il existe une variable de classe (dont on ne connais pas le nom car il n'est pas donné dans la doc) qui mémorise le centre de notification par défaut. Et la méthode de classe "defaultCenter" de cette classe NSNotificationCenter, elle ne fait que retourner la valeur de cette variable (genre "return _defaultCenter;")
(*)enfin si on peut faire ça mais c'est dans des cas très particuliers (objet classe) qui sont loin d'être utilisés tous les jours et qui est un concept peut être un peu tôt à aborder
Pour l'illustrer, je vais prendre un exemple :
- (void)rond {
int rayon = 20;
int r = rayon;
+ (void)changerRayon:int newrayon {
r = newrayon;
}
Bon je ne sais pas si mon code est correct, mais en fait c'est pour savoir si dans mon cas précis, si je crée 2 instances de ma classe rond1 et rond2, est ce qu'en envoyant le message [rond1 changerRayon:30] je change aussi la valeur de la variable de mon objet rond2, ou bien je change seulement la valeur par défaut des prochaine instances de ma classe, ou tout simplement ça ne marche pas du tout ?.
Une variable d'instance est propre à un objet : chaque objet peut avoir une valeur différente pour cette variable d'instance.
Ils possèdent tous la propriété (la variable d'instance), mais poru chaque objet elle peut avoir des valeurs différentes.
Exemple : tu te fabriques une classe voiture, et tu lui rajoutes une variable d'instance "couleur"... et bien -- et encore heureux -- chaque voiture aura une couleur, mais toutes les voitures ne sont pas obligées d'avoir la même !
Par contre ton code pour la méthode "rond" me gêne... Il ne renvoie rien ? Son nom n'est pas très explicite il ne crée pas un nouveau rond, il modifie juste ses réglages avec une valeur fixe... et en plus rayon et r ne sont pas des variables d'instance, mais jsute des variables temporaires créées dans le corps de ta fonction "rond" et qui seront donc détruites dès la sortie (l'execution) de cette méthode !
Je pense que ce que tu souhaitais faire c'est (1) créer une classe "Rond" qui possède une variable d'instance "rayon" (propriété de tes objets Rond : un rond est entre auters défini par son rayon, ce qui justifie la variable d'instance)... puis (2) surcharger la méthode "init" pour que par défaut lors de l'initialisation d'un nouveau objet de classe "Rond", son rayon soit initialisé à la valeur 20 ! Tu peux aussi te créer une méthode "initWithRayon:CenterX:CenterY:" (voire même des méthodes de commodité qui gèrent l'autorelease, mais là je pense pas que tu sois prêt vu que tu ne maà®trises pas encore la gestion de la mémoire).
Ce sont, pour information, des méthodes qui n'ont pas d'implémentation (et qui ne peuvent donc pas être appelées directement ), c'est à dire pas de code défini. Elles servent juste à signaler que la classe répond à cette méthode, mais pour l'utiliser il faut qu'elle soit définie dans une sous-classe.
Les classes possédant des méthodes virtuelles sont des classes abstraites : elles ne peuvent être utilisées directement, il faut les sous-classer et définir le code de ces méthodes virtuelles dans les sous-classes pour pouvoir les utiliser.
Par exemple on pourrait très bien imaginer une clase abstraite "figure" avec une méthode virtuelle "aire" (virtuelle donc qui n'a pas de code au niveau de la classe "figure", en effet on ne sait pas comment calculer l'aire d'une figure quelconque, il faut savori de quelle figure il s'agit. mais on sait que toute figure fermée a une aire donc il est logique que la méthode permettant d'en renvoyer sa valeur soit au niveau de la classe mère commune à toutes les figures.
Ensuite, on peut créer une classe "rectangle" de même qu'une classe "rond" et "triangle" dérivant toutes de la classe "figure". Chaque classe aura à définir un code pour la méthode "aire", qui sera différent selon la sous-classe (différent selon le type de figure).
Il est alors possible de créer des objets de type rectangle, rond ou triangle (mais pas de créer des objets ayant pour classe "figure" directement, car c'est une classe abstraite). Et on pourra très bien faire :
Merci des explications.
En résumé :
* méthode virtuelle et classe absraites sont à sous classer,
* variable de classe = variable partagée par tous les objets de cette classe.
Mais du coup, comment se déclare une variable de classe ?
Et bien c'est comme pour les méthodes statiques auxquelles je faisais allusion en C++.
Une méthode statique (ou méthode de classe en Obj-C) c'est une méthode qu'on appele indépendament de l'instanciation. Ok?
Et bien pour tes variables de classe c'est la même chose. Si tu veux avoir une variable de classe, il te suffit de la déclarer en variable statique.
Et bien sûr, tu créeras Les méthodes de classes qui vont bien pour la manipuler.
En réalité en Objective-C il n'existe pas de "variables de classes", on ne peut pas rajouter de variables à l'objet classe lui-même.
Le truc pour contourner ça c'est les variables statiques. Tu crées une variable globale ou mieux, une variable interne à la fonction mais en la précisant "static", ce qui permet de faire en sorte (statut un peu particulier, c'est pas forcément une bonne idée d'introduire cette notion si tôt mais tant pis) que lors du prochain appel elle se rappelle son ancienne valeur (en fait c'est une variable globale mais qui n'est accessible que dans le scope de la fonction, ce qui évite les risques de modifications extérieures).
Et ensuite tu crées une méthode par exemple : Voilà l'idée
Au premier appel _sharedInstance vaudra "nil", mais aux appels suivants, (et ce uniquement parce que _sharedInstance est déclaré avec le mot clé "static"), elle se rappellera sa valeur (qui ne sera plus "nil" à cause du alloc/init effectué lors du premier appel) !
quelques infos par là (en anglais)
[EDIT] ah et y'a ça aussi, et en français, lui