Was ist der Unterschied zwischen Klassen- und Instanzmethoden?

448

Was ist der Unterschied zwischen einer Klassenmethode und einer Instanzmethode?

Sind Instanzmethoden die Accessoren (Getter und Setter), während Klassenmethoden so ziemlich alles andere sind?

Hingebungsvoll
quelle

Antworten:

673

Wie die meisten anderen Antworten bereits sagten, verwenden Instanzmethoden eine Instanz einer Klasse, während eine Klassenmethode nur mit dem Klassennamen verwendet werden kann. In Objective-C sind sie folgendermaßen definiert:

@interface MyClass : NSObject

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

@end

Sie könnten dann so verwendet werden:

[MyClass aClassMethod];

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

Einige Beispiele aus der Praxis für Klassenmethoden sind die Convenience-Methoden für viele Foundation-Klassen wie NSString's +stringWithFormat:oder NSArray' s +arrayWithArray:. Eine Instanz Methode wäre NSArray‚s - -countMethode.

Cory Kilger
quelle
7
Gute Antwort. Es ist auch erwähnenswert, dass Sie eine bestimmte Kurzschreibweise zur Beschreibung von Methoden sehen. Beispiel: + [NSString stringWithFormat:] ist die Klassenmethode + stringWithFormat: on NSString; - [NSArray objectAtIndex:] ist eine Instanzmethode. Methoden mit mehreren Selektorteilen sind wie folgt geschrieben: [NSMutableDictionary setObject: forKey:] usw. Diese Notation wird häufig in Cocoa-Antworten, in der Dokumentation und in Xcode angezeigt.
Quinn Taylor
149
Ich würde hinzufügen, dass eine Klassenmethode in vielen anderen Sprachen als "statische" Methode bezeichnet wird. Um die ursprüngliche Frage zu beantworten, sind Accessoren Instanzmethoden, da sie den Status einer bestimmten Instanz festlegen und abrufen. Im obigen Beispiel gibt NSArray count die Anzahl der Objekte in einer bestimmten Instanz zurück.
Brian Pan
2
"Während eine Klassenmethode nur mit dem Klassennamen verwendet werden kann." oder das Klassenobjekt
user102008
2
Entschuldigung für meine Aufregung ... aber ich habe gerade den Unterschied und sein Potenzial gelernt. Klassenmethoden rocken und Singleton-Klassen auch! ufff Ich habe mich verliebt! <3
Pavan
2
@BrianPan statische und Klassenmethoden sind nicht identisch. Sie sind ähnlich, aber der Grund, warum sie unterschiedlich benannt werden, ist, dass sie unterschiedlich funktionieren. Beispielsweise können statische Methoden nicht überschrieben werden.
Sulthan
190

Alle technischen Details wurden in den anderen Antworten ausführlich behandelt. Ich möchte nur eine einfache Analogie teilen, die meiner Meinung nach den Unterschied zwischen einer Klasse und einer Instanz gut veranschaulicht:

Geben Sie hier die Bildbeschreibung ein

Eine Klasse ist wie die Blaupause eines Hauses: Sie haben nur eine Blaupause und (normalerweise) können Sie mit der Blaupause allein nicht so viel anfangen.

Geben Sie hier die Bildbeschreibung ein

Eine Instanz (oder ein Objekt ) ist das tatsächliche Haus , das Sie basierend auf der Blaupause bauen: Sie können viele Häuser aus derselben Blaupause bauen. Sie können dann die Wände in jedem der Häuser in einer anderen Farbe streichen, genauso wie Sie die Eigenschaften jeder Instanz einer Klasse unabhängig voneinander ändern können, ohne die anderen Instanzen zu beeinflussen.

Johannes Fahrenkrug
quelle
6
@JohannesFahrenkrug Hier wurde das Konzept für Klasse und Objekt gut erklärt. Ist nicht die eigentliche Frage für difference between class method and an instance method ;
Shekhu
1
Perfekte Erklärung von Klasse gegen Instanz einer Klasse. Klassen sind für Neulinge ein seltsames Konzept, und dies erklärt es auf seine grundlegendste Weise.
Alex McPherson
1
@ JohannesFahrenkrug wirklich eine gute Erklärung, die mich darüber nachdenken ließ, wie beide sich unterscheiden und wann ich beide verwenden sollte
ChenSmile
1
So eine tolle Erklärung :)
Praveenkumar
1
Gute Analogie. Bitte jemand gibt diesem Kerl ein Jahr lang Pizza.
GeneCode
102

Wie die anderen Antworten bereits sagten, arbeiten Instanzmethoden mit einem Objekt und haben Zugriff auf seine Instanzvariablen, während eine Klassenmethode mit einer Klasse als Ganzes arbeitet und keinen Zugriff auf die Variablen einer bestimmten Instanz hat (es sei denn, Sie übergeben die Instanz als Parameter).

Ein gutes Beispiel für eine Klassenmethode ist eine Zählermethode, die die Gesamtzahl der Instanzen einer Klasse zurückgibt. Klassenmethoden beginnen mit a +, während Instanzmethoden mit a beginnen -. Zum Beispiel:

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]);

Ausgabe: Alter: 0 Anzahl der Personen: 2

Ein anderes Beispiel ist, wenn Sie eine Methode haben, die der Benutzer aufrufen kann, manchmal ist es gut, diese zu einer Klassenmethode zu machen. Wenn Sie beispielsweise eine Klasse namens MathFunctions haben, können Sie dies tun:

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

Dann würde der Benutzer anrufen:

[MathFunctions square:34];

ohne jemals die Klasse instanziieren zu müssen!

Sie können auch Klassenfunktionen verwenden, um automatisch freigegebene Objekte wie NSArrays zurückzugeben

+ (NSArray *)arrayWithObject:(id)object

Das nimmt ein Objekt, fügt es in ein Array ein und gibt eine automatisch freigegebene Version des Arrays zurück, die nicht speicherverwaltet werden muss, ideal für temperamentvolle Arrays und was nicht.

Ich hoffe du verstehst jetzt wann und / oder warum du Klassenmethoden anwenden solltest !!

micmoo
quelle
1
micmoo, könnte ich vorschlagen, dass Sie "static int numberOfPeople = 0;" in Code formatiertem Text? Ich war verwirrt, bis ich es über dem Beispielcode bemerkte. Davon abgesehen eine wirklich prägnante Antwort.
Mobibob
2
Verzeihen Sie die Verwirrung meines Neulings, aber warum benötigen Sie sowohl die Instanzvariable "age" als auch die Instanzmethode "age"? Werden Getter und Setter, beispielsweise die Variable "age", nicht mit @synthetize erstellt?
Selytch
@selytch "Alter" müsste als eine Eigenschaft definiert werden, um synthetisieren zu können.
Micah94
36

Eine Instanzmethode gilt für eine Instanz der Klasse (dh ein Objekt), während eine Klassenmethode für die Klasse selbst gilt.

In C # ist eine Klassenmethode als statisch markiert. Methoden und Eigenschaften, die nicht als statisch markiert sind, sind Instanzmethoden.

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}
Robert Horvick
quelle
1
Argh - Entschuldigung, ich habe gerade bemerkt, dass dies eine Obj-C-Frage war. Hoffentlich gilt meine Antwort weiterhin, aber bitte stimmen Sie ab oder stimmen Sie ab, um sie zu löschen.
Robert Horvick
6
Keinen Schaden angerichtet. Der erste Teil Ihrer Antwort ist als allgemeines OOP-Prinzip korrekt und gilt definitiv für Objective-C. Sie können "Objective-C" zu Ihrer Liste der zu ignorierenden Tags hinzufügen, wenn Sie solche Fragen nicht sehen möchten, obwohl jede Teilnahme sicherlich willkommen ist. :-)
Quinn Taylor
16

Die Antwort auf Ihre Frage ist nicht spezifisch für Objective-C. In verschiedenen Sprachen können Klassenmethoden jedoch als statische Methoden bezeichnet werden.

Der Unterschied zwischen Klassenmethoden und Instanzmethoden ist

Klassenmethoden

  • Arbeiten Sie mit Klassenvariablen (sie können nicht auf Instanzvariablen zugreifen).
  • Es ist nicht erforderlich, dass ein zu instanziierendes Objekt angewendet wird
  • Manchmal kann es sich um einen Codegeruch handeln (einige OOP-Neulinge verwenden ihn als Krücke, um strukturierte Programmierung in einer OO-Umgebung durchzuführen).

Instanzmethoden

  • Arbeiten Sie mit Instanzvariablen und Klassenvariablen
  • Muss ein instanziiertes Objekt haben, an dem gearbeitet werden kann
hhafez
quelle
Instanzmethoden können mit Klassenvariablen arbeiten?
13.
16

Ich denke, der beste Weg, dies zu verstehen, ist allocundinit . Es war diese Erklärung, die es mir ermöglichte, die Unterschiede zu verstehen.

Klassenmethode

Eine Klassenmethode wird auf die gesamte Klasse angewendet. Wenn Sie die allocMethode überprüfen , handelt es sich um eine Klassenmethode, die mit dem gekennzeichnet ist+ vor der Methodendeklaration angegeben ist. Es ist eine Klassenmethode, da sie auf die Klasse angewendet wird, um eine bestimmte Instanz dieser Klasse zu erstellen.

Instanzmethode

Sie verwenden eine Instanzmethode, um eine bestimmte Instanz einer Klasse zu ändern, die für diese Instanz und nicht für die gesamte Klasse eindeutig ist. initBeispiel (mit einem -vor der Methodendeklaration gekennzeichnet) ist eine Instanzmethode, da Sie normalerweise die Eigenschaften dieser Klasse ändern, nachdem sie mit erstellt wurde alloc.

Beispiel

NSString *myString = [NSString alloc];

Sie rufen die Klassenmethode allocauf, um eine Instanz dieser Klasse zu generieren. Beachten Sie, dass der Empfänger der Nachricht eine Klasse ist.

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

Sie ändern die NSStringaufgerufene Instanz , myStringindem Sie einige Eigenschaften für diese Instanz festlegen. Beachten Sie, dass der Empfänger der Nachricht eine Instanz (Objekt der Klasse NSString) ist.

Adam Waite
quelle
Was meinst du mit "Alloc" -Methode überprüfen? Können Sie mich auf eine bestimmte Stelle in der Dokumentation verweisen? (bearbeiten) -> ahh egal, ja, in den NSObject-Dokumenten steht, dass unter "Aufgaben" - developer.apple.com/library/ios/documentation/cocoa/reference/…
Ethan Parker
Sie müssen nicht wirklich verstehen, was es wirklich tut, um dies zu erfassen, nur dass es auf die Klasse angewendet wird. Einfach ausgedrückt: allocWeist dem Objekt genügend Speicher zu, initändert den Inhalt dieser Speicheradressen, um den Status des Objekts zu definieren. Wir können ein Objekt nur ändern, wenn ein Leerzeichen vorhanden ist, in dem es geändert werden kann. Daher verwenden wir es allocfür die Klasse, die entscheidet, dass wir dieses Leerzeichen erhalten.
Adam Waite
6

Klassenmethoden werden normalerweise verwendet, um Instanzen dieser Klasse zu erstellen

Gibt beispielsweise [NSString stringWithFormat:@"SomeParameter"];eine NSStringInstanz mit dem Parameter zurück, der an sie gesendet wird. Da es sich um eine Klassenmethode handelt, die ein Objekt seines Typs zurückgibt, wird sie auch als Convenience-Methode bezeichnet.

iosrookie
quelle
6

Also wenn ich es richtig verstehe.

Für eine classMethode müssen Sie keine Instanz dieses Objekts zuweisen, um es zu verwenden / zu verarbeiten. Eine classMethode ist in sich geschlossen und kann ohne Abhängigkeit vom Zustand eines Objekts dieser Klasse betrieben werden. EINclass Methode wird erwartet, dass sie Speicher für ihre gesamte eigene Arbeit zuweist und die Zuordnung aufhebt, wenn dies erledigt ist, da keine Instanz dieser Klasse Speicher freigeben kann, der in früheren Aufrufen der Klassenmethode zugewiesen wurde.

EIN instance Methode ist genau das Gegenteil. Sie können es nur aufrufen, wenn Sie eine Instanz dieser Klasse zuweisen. Es ist wie eine normale Klasse, die einen Konstruktor hat und einen Destruktor haben kann (der den gesamten zugewiesenen Speicher bereinigt).

Höchstwahrscheinlich (es sei denn, Sie schreiben eine wiederverwendbare Bibliothek, sollten Sie keine classVariable benötigen .

Siddharth
quelle
1
Ein offensichtlicher Fall, in dem Sie Klassenmethoden benötigen, ist die Erstellung von Instanzen. Sie müssen in der Lage sein, Instanzen zu erstellen, ohne dass noch Instanzen vorhanden sind. Andernfalls kann die erste Instanz niemals erstellt werden. Deshalb ist und muss + alloc eine Klassenmethode sein.
Gnasher729
4

Instanzmethoden arbeiten mit Instanzen von Klassen (dh "Objekten"). Klassenmethoden sind Klassen zugeordnet (die meisten Sprachen verwenden das Schlüsselwort staticfür diese Typen).

nervös
quelle
3

Nehmen wir zum Beispiel ein Spiel, in dem viele Autos erscheinen. Jedes gehört zur Klasse CCar. Wenn ein Auto instanziiert wird, ruft es an

[CCar registerCar:self]

So kann die CCar-Klasse eine Liste aller instanziierten CCar erstellen. Angenommen, der Benutzer beendet ein Level und möchte alle Autos entfernen. Sie können entweder: 1- eine Liste aller manuell erstellten CCar durchgehen und dies tun whicheverCar.remove(); oder 2- CCar eine removeAllCars-Methode hinzufügen, die dies erledigt für Sie, wenn Sie [CCar removeAllCars] aufrufen. Dh allCars[n].remove();

Sie können dem Benutzer beispielsweise erlauben, eine Standardschriftgröße für die gesamte App anzugeben, die beim Start geladen und gespeichert wird. Ohne die Klassenmethode müssen Sie möglicherweise so etwas tun

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

Mit der Klassenmethode könnten Sie durchkommen [FontHandler getDefaultFontSize].

Bei Ihrer Funktion removeVowels werden Sprachen wie C # mit bestimmten Methoden wie toLower oder toUpper tatsächlich beides haben.

zB myString.removeVowels() und String.removeVowels(myString) (in ObjC wäre das [String removeVowels:myString]).

In diesem Fall ruft die Instanz wahrscheinlich die Klassenmethode auf, sodass beide verfügbar sind. dh

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

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

im Grunde myString.toLower() Anrufe [String toLower:ownValue]

Es gibt keine endgültige Antwort, aber wenn Sie Lust haben, eine Klassenmethode einzuschieben, wird Ihr Code verbessert, probieren Sie es aus und denken Sie daran, dass Sie mit einer Klassenmethode nur andere Klassenmethoden / -variablen verwenden können.

Sichelstein
quelle
3

Klassenmethoden

sind Methoden, die als statisch deklariert sind. Die Methode kann aufgerufen werden, ohne eine Instanz der Klasse zu erstellen. Klassenmethoden können nur für Klassenmitglieder und nicht für Instanzmitglieder ausgeführt werden, da Klassenmethoden keine Instanzmitglieder kennen. Instanzmethoden der Klasse können auch nicht innerhalb einer Klassenmethode aufgerufen werden, es sei denn, sie werden für eine Instanz dieser Klasse aufgerufen.

Instanzmethoden

Auf der anderen Seite muss eine Instanz der Klasse vorhanden sein, bevor sie aufgerufen werden kann. Daher muss eine Instanz einer Klasse mithilfe des neuen Schlüsselworts erstellt werden. Instanzmethoden arbeiten mit bestimmten Instanzen von Klassen. Instanzmethoden werden nicht als statisch deklariert.

iCrazyDev
quelle
Es kann auch mit dem Schlüsselwort "alloc" erstellt werden, nicht nur mit dem Schlüsselwort "new". Außerdem verlangt Objective-C nicht, dass eine Instanz vorhanden ist, um eine Instanzmethode aufzurufen. Sie können Nachrichten an einen Nullzeiger senden.
Elviss Strazdins
3

In Objective-C beginnen alle Methoden entweder mit einem "-" oder "+". Beispiel:

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

+ (void) classMethod;
@end

Die Zeichen "+" und "-" geben an, ob eine Methode eine class methododer eine istinstance method .

Der Unterschied wäre klar, wenn wir diese Methoden aufrufen. Hier werden die Methoden in deklariert MyClass.

instance method erfordern eine Instanz der Klasse:

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

Innerhalb MyClassanderer Methoden können Instanzmethoden wie folgt aufgerufen MyClasswerden self:

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

Aber class methodsmuss auf die Klasse selbst aufgerufen werden:

[MyClass classMethod];

Oder:

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

Das wird nicht funktionieren:

// Error
[myClass classMethod];
// Error
[self classMethod];
Tulon
quelle
3

KLASSENMETHODEN


Eine Klassenmethode erstellt normalerweise entweder eine neue Instanz der Klasse oder ruft einige globale Eigenschaften der Klasse ab. Klassenmethoden arbeiten nicht mit einer Instanz oder haben keinen Zugriff auf Instanzvariablen.


INSTANZMETHODEN


Eine Instanzmethode arbeitet mit einer bestimmten Instanz der Klasse. Die von Ihnen implementierte Zugriffsmethode sind beispielsweise alle Instanzmethoden. Sie verwenden sie, um die Instanzvariablen eines bestimmten Objekts festzulegen oder abzurufen.


AUFRUFEN


Um eine Instanzmethode aufzurufen, senden Sie die Nachricht an eine Instanz der Klasse.

Um eine Klassenmethode aufzurufen, senden Sie die Nachricht direkt an die Klasse.


Quelle: IOS - Objective-C - Klassenmethoden und Instanzmethoden

Nam N. HUYNH
quelle
1

Klassenmethoden können den Wert einer Instanzvariablen nicht ändern oder kennen. Dies sollte das Kriterium sein, um zu wissen, ob eine Instanzmethode eine Klassenmethode sein kann.

Deepee
quelle
-1 von mir, weil Sie die Instanz an die Klassenmethode übergeben können und sie die Werte ihrer Variablen ändern und kennen kann.
Elviss Strazdins
1

Denken Sie auch daran, dass die gleiche Idee für Variablen gilt. Sie werden auf Begriffe wie statisch, Mitglied, Instanz, Klasse usw. stoßen, wenn Sie über Variablen sprechen, wie Sie es für Methoden / Funktionen tun würden.

Es scheint, dass der in der Obj-C-Community gebräuchliche Begriff ivar ist, zum Beispiel variabel, aber ich bin noch kein Obj-C-Typ.

Halbduplex
quelle
1

Bei einer Aktualisierung der obigen Antworten stimme ich zu, dass Instanzmethoden eine Instanz einer Klasse verwenden, während eine Klassenmethode nur mit dem Klassennamen verwendet werden kann.

Es gibt keinen Unterschied mehr zwischen Instanzmethode und Klassenmethode, nachdem in Objective-C eine automatische Referenzzählung durchgeführt wurde.

Zum Beispiel [NS StringWithformat:..]eine Klassenmethode und [[NSString alloc] initwihtformat:..]eine Instanzmethode, beide sind nach ARC gleich

user1292809
quelle
1

Hinweis: Dies ist nur im Pseudocode-Format

Klassenmethode

Fast alles, was es tun muss, ist während der Kompilierungszeit . Es sind keine Benutzereingaben erforderlich, und die Berechnung basiert nicht auf einer Instanz. Alles daran basiert auf der Klasse / Blaupause - was einzigartig ist, dh Sie haben nicht mehrere Blaupausen für eine Klasse. Können Sie während der Kompilierungszeit verschiedene Variationen haben? Nein, daher ist die Klasse eindeutig. Unabhängig davon, wie oft Sie eine Klassenmethode aufrufen, ist der Zeiger, der darauf zeigt, derselbe.

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

Instanzmethode

Im Gegenteil, die Instanzmethode findet zur Laufzeit statt, da Sie erst dann eine Instanz von etwas erstellt haben, das bei jeder Instanziierung variieren kann.

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.

Wenn Sie aus anderen Sprachen kommen Statische Methoden sind dieselben wie Klassenmethoden.
Wenn Sie von Swift kommen, sind die Typmethoden mit den Klassenmethoden identisch.

Honig
quelle
0

Zu den obigen Antworten hinzufügen

Die Klassenmethode funktioniert für Klassen. Wir verwenden diese Methode für allgemeine Zwecke, z. B. + stringWithFormat, Klassengröße und vor allem für init usw.

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

Die Instanzmethode funktioniert für eine Instanz einer Klasse, nicht für eine Klasse, wie wir zwei Personen haben, und wir möchten den Rest jeder Instanz separat kennenlernen. Hier müssen wir die Instanzmethode verwenden. Weil es keine allgemeine Antwort zurückgibt. zB wie bestimmen die Anzahl der NSSArray etc.

[johnson getAccountBalance];
[ankit getAccountBalance];
Ankit garg
quelle