Quelle est la différence entre les méthodes de classe et d'instance?

448

Quelle est la différence entre une méthode de classe et une méthode d'instance?

Les méthodes d'instance sont-elles les accesseurs (getters et setters) tandis que les méthodes de classe sont à peu près tout le reste?

Dévoué
la source

Réponses:

673

Comme la plupart des autres réponses l'ont dit, les méthodes d'instance utilisent une instance d'une classe, tandis qu'une méthode de classe peut être utilisée avec uniquement le nom de la classe. Dans Objective-C, ils sont définis ainsi:

@interface MyClass : NSObject

+ (void)aClassMethod;
- (void)anInstanceMethod;

@end

Ils pourraient alors être utilisés ainsi:

[MyClass aClassMethod];

MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];

Certains exemples réels de méthodes de classe sont les méthodes pratiques de nombreuses classes Foundation comme NSString's +stringWithFormat:ou NSArray' +arrayWithArray:. Une méthode d'instance serait NSArrayla -countméthode de.

Cory Kilger
la source
7
Bonne réponse. Il convient également de noter que vous verrez une notation abrégée particulière pour décrire les méthodes. Par exemple, + [NSString stringWithFormat:] est la méthode de classe + stringWithFormat: on NSString; - [NSArray objectAtIndex:] est une méthode d'instance. Les méthodes avec plusieurs parties de sélecteur sont écrites comme - [NSMutableDictionary setObject: forKey:] etc. Vous verrez souvent cette notation dans les réponses Cocoa, la documentation et dans Xcode.
Quinn Taylor
149
J'ajouterais qu'une méthode de classe est appelée méthode "statique" dans de nombreuses autres langues. Et pour répondre à la question d'origine, les accesseurs sont des méthodes d'instance car ils définissent et obtiennent l'état d'une instance spécifique. Dans l'exemple ci-dessus, NSArray count renvoie le nombre d'objets dans une instance spécifique.
Brian Pan
2
"alors qu'une méthode de classe peut être utilisée avec juste le nom de la classe." ou l'objet de classe
user102008
2
Désolé pour mon enthousiasme ... mais je viens d'apprendre la différence et son potentiel. les méthodes de classe rock et les classes singleton aussi! ufff je suis tombé amoureux! <3
Pavan
2
Les méthodes statiques et de classe @BrianPan ne sont pas les mêmes. Ils sont similaires mais la raison pour laquelle ils sont nommés différemment est qu'ils fonctionnent différemment. Par exemple, les méthodes statiques ne peuvent pas être remplacées.
Sulthan
190

Tous les détails techniques ont été bien couverts dans les autres réponses. Je veux juste partager une analogie simple qui, je pense, illustre bien la différence entre une classe et une instance:

entrez la description de l'image ici

Une classe est comme le plan d'une maison: vous n'avez qu'un seul plan et (généralement) vous ne pouvez pas faire grand-chose avec le plan seul.

entrez la description de l'image ici

Une instance (ou un objet ) est la maison réelle que vous construisez en fonction du plan: vous pouvez construire de nombreuses maisons à partir du même plan. Vous pouvez ensuite peindre les murs d'une couleur différente dans chacune des maisons, tout comme vous pouvez modifier indépendamment les propriétés de chaque instance d'une classe sans affecter les autres instances.

Johannes Fahrenkrug
la source
6
@JohannesFahrenkrug Bien expliqué le concept de classe et d'objet ici. La vraie question n'est pas pour difference between class method and an instance method ;
Shekhu
1
Explication parfaite de la classe contre l'instance d'une classe. Les cours sont un concept étrange pour les débutants et cela l'explique de sa manière la plus fondamentale.
Alex McPherson
1
@JohannesFahrenkrug vraiment une bonne explication, ce qui m'a fait penser comment les deux r diff et quand les utiliser
ChenSmile
1
Une telle grande explication :)
Praveenkumar
1
Bonne analogie. S'il vous plaît, quelqu'un donne à ce gars un approvisionnement d'un an en pizzas.
GeneCode
102

Comme les autres réponses l'ont dit, les méthodes d'instance fonctionnent sur un objet et ont accès à ses variables d'instance, tandis qu'une méthode de classe fonctionne sur une classe dans son ensemble et n'a pas accès aux variables d'une instance particulière (sauf si vous passez l'instance en tant que paramètre).

Un bon exemple d'une méthode de classe est une méthode de type compteur, qui renvoie le nombre total d'instances d'une classe. Les méthodes de classe commencent par un +, tandis que celles d'instance commencent par un -. Par exemple:

static int numberOfPeople = 0;

@interface MNPerson : NSObject {
     int age;  //instance variable
}

+ (int)population; //class method. Returns how many people have been made.
- (id)init; //instance. Constructs object, increments numberOfPeople by one.
- (int)age; //instance. returns the person age
@end

@implementation MNPerson
- (id)init{
    if (self = [super init]){
          numberOfPeople++;
          age = 0;
    }    
    return self;
}

+ (int)population{ 
     return numberOfPeople;
}

- (int)age{
     return age;
}

@end

main.m:

MNPerson *micmoo = [[MNPerson alloc] init];
MNPerson *jon = [[MNPerson alloc] init];
NSLog(@"Age: %d",[micmoo age]);
NSLog(@"%Number Of people: %d",[MNPerson population]);

Sortie: Âge: 0 Nombre de personnes: 2

Un autre exemple est que si vous avez une méthode que vous souhaitez que l'utilisateur puisse appeler, il est parfois utile d'en faire une méthode de classe. Par exemple, si vous avez une classe appelée MathFunctions, vous pouvez le faire:

+ (int)square:(int)num{ 
      return num * num;
}

Alors, l'utilisateur appellerait:

[MathFunctions square:34];

sans jamais avoir à instancier la classe!

Vous pouvez également utiliser des fonctions de classe pour renvoyer des objets libérés automatiquement, comme NSArray

+ (NSArray *)arrayWithObject:(id)object

Cela prend un objet, le place dans un tableau et renvoie une version libérée automatiquement du tableau qui n'a pas besoin d'être gérée en mémoire, idéale pour les tableaux temporaires et autres.

J'espère que vous comprenez maintenant quand et / ou pourquoi utiliser des méthodes de classe !!

micmoo
la source
1
micmoo, puis-je vous suggérer de mettre le "static int numberOfPeople = 0;" dans du texte au format code? J'étais confus jusqu'à ce que je le remarque au-dessus de l'exemple de code. A part ça, une réponse vraiment concise.
mobibob
2
Pardonnez ma confusion de débutant, mais pourquoi avez-vous besoin à la fois de la variable d'instance "age" et de la méthode d'instance "age"? Est-ce que getter et setter, par exemple, la variable "age" ne sera pas créée avec @synthetize?
selytch
@selytch "age" devrait être défini comme une propriété pour pouvoir utiliser la synthèse.
micah94
36

Une méthode d'instance s'applique à une instance de la classe (c'est-à-dire un objet) tandis qu'une méthode de classe s'applique à la classe elle-même.

En C #, une méthode de classe est marquée comme statique. Les méthodes et propriétés non marquées statiques sont des méthodes d'instance.

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}
Robert Horvick
la source
1
Argh - désolé, je viens de remarquer que c'était une question Obj-C. J'espère que ma réponse s'applique toujours, mais veuillez voter contre ou voter pour supprimer.
Robert Horvick
6
Pas de mal. La première partie de votre réponse est correcte en tant que principe général de POO, et elle s'applique certainement à Objective-C. Vous pouvez ajouter "objective-c" à votre liste de balises à ignorer si vous ne voulez pas voir de telles questions, bien que toute participation soit certainement la bienvenue. :-)
Quinn Taylor
16

La réponse à votre question n'est pas spécifique à objective-c, mais dans différentes langues, les méthodes de classe peuvent être appelées méthodes statiques.

La différence entre les méthodes de classe et les méthodes d'instance est

Méthodes de classe

  • Opérer sur des variables de classe (elles ne peuvent pas accéder aux variables d'instance)
  • Ne nécessite pas qu'un objet soit instancié pour être appliqué
  • Parfois, cela peut être une odeur de code (certaines personnes qui sont nouvelles dans la POO utilisent comme béquille pour faire de la programmation structurée dans un environnement OO)

Méthodes d'instance

  • Opérer sur les variables d'instances et les variables de classe
  • Doit avoir un objet instancié pour fonctionner
Hhafez
la source
Les méthodes d'instance peuvent fonctionner sur des variables de classe?
蘇健豪
16

Je pense que la meilleure façon de comprendre cela est de regarder allocet init. C'est cette explication qui m'a permis de comprendre les différences.

Méthode de classe

Une méthode de classe est appliquée à la classe dans son ensemble. Si vous vérifiez la allocméthode, il s'agit d'une méthode de classe indiquée par +avant la déclaration de méthode. C'est une méthode de classe car elle est appliquée à la classe pour créer une instance spécifique de cette classe.

Méthode d'instance

Vous utilisez une méthode d'instance pour modifier une instance spécifique d'une classe qui est unique à cette instance, plutôt qu'à la classe dans son ensemble. initpar exemple (indiqué par un -avant la déclaration de méthode), est une méthode d'instance car vous modifiez normalement les propriétés de cette classe après qu'elle a été créée avec alloc.

Exemple

NSString *myString = [NSString alloc];

Vous appelez la méthode de classe allocafin de générer une instance de cette classe. Remarquez comment le destinataire du message est une classe.

[myString initWithFormat:@"Hope this answer helps someone"];

Vous modifiez l'instance de NSStringappelé myStringen définissant certaines propriétés sur cette instance. Remarquez comment le destinataire du message est une instance (objet de classe NSString).

Adam Waite
la source
Qu'entendez-vous par vérifier la méthode "alloc"? Pouvez-vous m'indiquer un endroit précis dans la documentation? (modifier) ​​-> ahh nevermind, oui dans les documents NSObject, il est dit que sous "Tâches" - developer.apple.com/library/ios/documentation/cocoa/reference/…
Ethan Parker
Vous n'avez pas vraiment besoin de comprendre ce que cela fait vraiment pour comprendre cela, juste qu'il est appliqué à la classe. En termes simples: allocalloue suffisamment de mémoire à l'objet, initmodifiera le contenu de ces adresses mémoire pour définir l'état de l'objet. Nous ne pouvons pas modifier un objet à moins qu'il y ait un espace pour le modifier, nous utilisons donc allocsur la classe qui décidera de nous donner cet espace.
Adam Waite
6

Les méthodes de classe sont généralement utilisées pour créer des instances de cette classe

Par exemple, [NSString stringWithFormat:@"SomeParameter"];renvoie une NSStringinstance avec le paramètre qui lui est envoyé. Par conséquent, comme il s'agit d'une méthode Class qui renvoie un objet de son type, elle est également appelée méthode de commodité.

iosrookie
la source
6

Donc, si je comprends bien.

Une classméthode n'a pas besoin que vous allouiez une instance de cet objet pour l'utiliser / le traiter. Une classméthode est autonome et peut fonctionner sans aucune dépendance de l'état d'un objet de cette classe. Une classméthode est censée allouer de la mémoire pour tout son travail et se désallouer lorsqu'elle est terminée, car aucune instance de cette classe ne pourra libérer de la mémoire allouée lors des appels précédents à la méthode class.

Une instanceméthode est tout le contraire. Vous ne pouvez l'appeler que si vous allouez une instance de cette classe. C'est comme une classe normale qui a un constructeur et peut avoir un destructeur (qui nettoie toute la mémoire allouée).

Selon toute probabilité (sauf si vous écrivez une bibliothèque réutilisable, vous ne devriez pas avoir besoin d'une classvariable.

Siddharth
la source
1
Un cas évident où vous avez besoin de méthodes de classe est la création d'instances. Vous devez pouvoir créer des instances sans en avoir encore, sinon la première instance ne pourra jamais être créée. C'est pourquoi + alloc est et doit être une méthode de classe.
gnasher729
4

Les méthodes d'instances fonctionnent sur les instances de classes (c'est-à-dire les "objets"). Les méthodes de classe sont associées aux classes (la plupart des langues utilisent le mot-clé staticpour ces gars-là).

eduffy
la source
3

Prenons par exemple un jeu où beaucoup de voitures sont générées .. chacune appartient à la classe CCar. Lorsqu'une voiture est instanciée, elle appelle

[CCar registerCar:self]

Ainsi, la classe CCar peut faire une liste de chaque CCar instanciée. Supposons que l'utilisateur termine un niveau et souhaite supprimer toutes les voitures ... vous pouvez soit: 1- parcourir une liste de tous les CCar que vous avez créés manuellement, et faire whicheverCar.remove(); ou 2- ajouter une méthode removeAllCars à CCar, qui le fera pour vous lorsque vous appelez [CCar removeAllCars]. C'est à dire allCars[n].remove();

Ou, par exemple, vous autorisez l'utilisateur à spécifier une taille de police par défaut pour l'ensemble de l'application, qui est chargée et enregistrée au démarrage. Sans la méthode de classe, vous pourriez avoir à faire quelque chose comme

fontSize = thisMenu.getParent().fontHandler.getDefaultFontSize();

Avec la méthode de classe, vous pourriez vous en tirer [FontHandler getDefaultFontSize].

En ce qui concerne votre fonction removeVowels, vous constaterez que des langages comme C # ont en fait les deux avec certaines méthodes telles que toLower ou toUpper.

par exemple myString.removeVowels() et String.removeVowels(myString) (dans ObjC ce serait [String removeVowels:myString]).

Dans ce cas, l'instance appelle probablement la méthode de classe, donc les deux sont disponibles. c'est à dire

public function toLower():String{
  return String.toLower();
}

public static function toLower( String inString):String{
 //do stuff to string..
 return newString;
}

essentiellement, les myString.toLower() appels [String toLower:ownValue]

Il n'y a pas de réponse définitive, mais si vous avez envie de pousser une méthode de classe dans améliorerait votre code, essayez-le et gardez à l'esprit qu'une méthode de classe ne vous permettra d'utiliser que d'autres méthodes / variables de classe.

faucille
la source
3

méthodes de classe

sont des méthodes qui sont déclarées comme statiques. La méthode peut être appelée sans créer d'instance de la classe. Les méthodes de classe ne peuvent fonctionner que sur les membres de classe et non sur les membres d'instance car les méthodes de classe ne connaissent pas les membres d'instance. Les méthodes d'instance de la classe ne peuvent pas non plus être appelées à partir d'une méthode de classe, sauf si elles sont appelées sur une instance de cette classe.

Méthodes d'instance

d'autre part, il faut qu'une instance de la classe existe avant de pouvoir être appelée, donc une instance d'une classe doit être créée en utilisant le nouveau mot-clé. Les méthodes d'instance fonctionnent sur des instances spécifiques de classes. Les méthodes d'instance ne sont pas déclarées comme statiques.

iCrazyDev
la source
Il peut également être créé avec le mot clé "alloc" non seulement le "nouveau". De plus, Objective-C n'exige pas qu'une instance existe pour appeler une méthode d'instance, vous pouvez envoyer des messages à un pointeur nul.
Elviss Strazdins
3

Dans Objective-C, toutes les méthodes commencent par un caractère "-" ou "+". Exemple:

@interface MyClass : NSObject
// instance method
- (void) instanceMethod;

+ (void) classMethod;
@end

Les caractères "+" et "-" spécifient si une méthode est respectivement a class methodou a instance method.

La différence serait claire si nous appelions ces méthodes. Ici, les méthodes sont déclarées dans MyClass.

instance method nécessite une instance de la classe:

MyClass* myClass = [[MyClass alloc] init];
[myClass instanceMethod];

A l'intérieur d' MyClassautres méthodes peuvent appeler des méthodes d'instance en MyClassutilisant self:

-(void) someMethod
{
    [self instanceMethod];
}

Mais, class methodsdoit être appelé sur la classe elle-même:

[MyClass classMethod];

Ou:

MyClass* myClass = [[MyClass alloc] init];
[myClass class] classMethod];

Cela ne fonctionnera pas:

// Error
[myClass classMethod];
// Error
[self classMethod];
Tulon
la source
3

MÉTHODES DE CLASSE


Une méthode de classe crée généralement une nouvelle instance de la classe ou récupère certaines propriétés globales de la classe. Les méthodes de classe ne fonctionnent pas sur une instance ou n'ont aucun accès à la variable d'instance.


MÉTHODES D'INSTANCE


Une méthode d'instance fonctionne sur une instance particulière de la classe. Par exemple, la méthode d'accesseurs que vous avez implémentée sont toutes des méthodes d'instance. Vous les utilisez pour définir ou obtenir les variables d'instance d'un objet particulier.


INVOQUER


Pour appeler une méthode d'instance, vous envoyez le message à une instance de la classe.

Pour appeler une méthode de classe, vous envoyez directement le message à la classe.


Source: IOS - Objective-C - Méthodes de classe et méthodes d'instance

Nam N. HUYNH
la source
1

Les méthodes de classe ne peuvent pas modifier ou connaître la valeur d'une variable d'instance. Cela devrait être le critère pour savoir si une méthode d'instance peut être une méthode de classe.

Deepee
la source
-1 de ma part, car vous pouvez passer l'instance à la méthode class et elle pourra changer et connaître les valeurs de ses variables.
Elviss Strazdins
1

Rappelez-vous également que la même idée s'applique aux variables. Vous rencontrerez des termes comme statique, membre, instance, classe et ainsi de suite lorsque vous parlerez de variables de la même manière que pour les méthodes / fonctions.

Il semble que le terme commun dans la communauté Obj-C soit ivar par exemple variable, mais je ne suis pas encore un gars Obj-C.

Half_Duplex
la source
1

Une mise à jour des réponses ci-dessus, je conviens que les méthodes d'instance utilisent une instance d'une classe, tandis qu'une méthode de classe peut être utilisée avec uniquement le nom de la classe.

Il n'y a plus de différence entre la méthode d'instance et la méthode de classe après que le comptage automatique des références a vu le jour dans Objective-C.

Par exemple, [NS StringWithformat:..]une méthode de classe et [[NSString alloc] initwihtformat:..]une méthode d'instance, les deux sont identiques après ARC

user1292809
la source
1

Remarque: Ceci est uniquement au format pseudo-code

Méthode de classe

Presque tout ce qu'il doit faire est pendant la compilation . Il n'a besoin d'aucune entrée utilisateur, ni son calcul basé sur une instance. Tout à ce sujet est basé sur la classe / le plan - qui est unique, c'est-à-dire que vous n'avez pas plusieurs plans pour une classe. Pouvez-vous avoir différentes variations pendant la compilation? Non, par conséquent, la classe est unique et donc quel que soit le nombre de fois que vous appelez une méthode de classe, le pointeur pointant vers elle sera le même.

PlanetOfLiving: return @"Earth" // No matter how many times you run this method...nothing changes.

Méthode d'instance

Au contraire, la méthode d'instance se produit pendant l'exécution, car c'est seulement alors que vous avez créé une instance de quelque chose qui peut varier à chaque instanciation.

initWithName: @"John" lastName: @"Doe"Age:12 @"cool"
initWithName: @"Donald" lastName: @"Drumpf"Age:5 attitude:@"He started"
initWithName: @"President" lastName: @"Obama"Age:54 attitude: @"Awesome"
//As you can see the value can change for each instance.

Si vous venez d'autres langages Les méthodes statiques sont les mêmes que les méthodes de classe.
Si vous venez de Swift, les méthodes de type sont les mêmes que les méthodes de classe.

Mon chéri
la source
0

Ajout aux réponses ci-dessus

La méthode de classe fonctionnera sur la classe, nous l'utiliserons à des fins générales où comme + stringWithFormat, la taille de la classe et surtout pour init etc

NSString *str = [NSString stringWithFormat:@"%.02f%%",someFloat]; 

La méthode d'instance fonctionnera sur une instance d'une classe et non sur une classe comme nous avons deux personnes et nous voulons connaître l'équilibre de chacune séparément ici, nous devons utiliser la méthode d'instance. Parce qu'il ne renverra pas de réponse générale. par exemple, comme déterminer le nombre de NSSArray, etc.

[johnson getAccountBalance];
[ankit getAccountBalance];
Garçon Ankit
la source