Qual è la differenza tra i metodi di classe e di istanza?


448

Qual è la differenza tra un metodo di classe e un metodo di istanza?

I metodi di istanza sono gli accessori (getter e setter) mentre i metodi di classe sono praticamente tutto il resto?

Risposte:


673

Come la maggior parte delle altre risposte ha detto, i metodi di istanza usano un'istanza di una classe, mentre un metodo di classe può essere usato solo con il nome della classe. In Objective-C sono definiti così:

@interface MyClass : NSObject

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

@end

Potrebbero quindi essere utilizzati in questo modo:

[MyClass aClassMethod];

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

Alcuni esempi reali di metodi di classe sono i metodi di praticità su molte classi della Fondazione come NSString" +stringWithFormat:o NSArray" +arrayWithArray:. Un metodo di istanza sarebbe NSArrayil -countmetodo di.


7
Buona risposta. Vale anche la pena notare che vedrai una particolare notazione abbreviata per la descrizione dei metodi. Ad esempio, + [NSString stringWithFormat:] è il metodo di classe + stringWithFormat: su NSString; - [NSArray objectAtIndex:] è un metodo di istanza. I metodi con più parti del selettore sono scritti come: [NSMutableDictionary setObject: forKey:] ecc. Vedrai spesso questa notazione nelle risposte, nella documentazione e in Xcode di Cocoa.
Quinn Taylor,

149
Vorrei aggiungere che un metodo di classe è chiamato un metodo "statico" in molte altre lingue. E per rispondere alla domanda originale, gli accessori sono metodi di istanza perché stanno impostando e ottenendo lo stato di un'istanza specifica. Nell'esempio sopra, il conteggio NSArray restituisce il numero di oggetti in un'istanza specifica.
Brian Pan,

2
"considerando che un metodo di classe può essere utilizzato solo con il nome della classe." o l'oggetto classe
user102008

2
Scusatemi per l'eccitazione ... ma ho appena imparato la differenza e il suo potenziale. i metodi di classe rock e così anche le classi singleton! ufff mi sono innamorato! <3
Pavan

2
I metodi statici e di classe @BrianPan non sono gli stessi. Sono simili ma il motivo per cui sono chiamati in modo diverso è che funzionano in modo diverso. Ad esempio, i metodi statici non possono essere sostituiti.
Sulthan,

190

Tutti i dettagli tecnici sono stati ben coperti nelle altre risposte. Voglio solo condividere una semplice analogia che penso illustra bene la differenza tra una classe e un'istanza:

inserisci qui la descrizione dell'immagine

Una classe è come il progetto di una casa: hai solo un modello e (di solito) non puoi fare così tanto con il modello da solo.

inserisci qui la descrizione dell'immagine

Un esempio (o un oggetto ) è l'attuale casa che si costruisce sulla base del progetto: È possibile costruire un sacco di case dallo stesso progetto. È quindi possibile dipingere le pareti di un colore diverso in ciascuna delle case, così come è possibile modificare in modo indipendente le proprietà di ciascuna istanza di una classe senza influenzare le altre istanze.


6
@JohannesFahrenkrug Qui ha ben spiegato il concetto di classe e oggetto. Non è la domanda vera per difference between class method and an instance method ;
Shekhu,

1
Spiegazione perfetta di Classe vs Istanza di una classe. Le classi sono un concetto strano per i neofiti e questo lo spiega nel suo modo più fondamentale.
Alex McPherson,

1
@JohannesFahrenkrug davvero una buona spiegazione, che mi ha fatto pensare a come entrambi sono diff e quando usare entrambi
ChenSmile,

1
Tale grande spiegazione :)
Praveenkumar l'

1
Buona analogia. Per favore qualcuno dà a questo ragazzo un anno di scorte di pizze.
GeneCode

102

Come hanno detto le altre risposte, i metodi di istanza operano su un oggetto e hanno accesso alle sue variabili di istanza, mentre un metodo di classe opera su una classe nel suo insieme e non ha accesso alle variabili di una particolare istanza (a meno che non passi l'istanza come parametro).

Un buon esempio di un metodo di classe è un metodo di contro-tipo, che restituisce il numero totale di istanze di una classe. I metodi di classe iniziano con a +, mentre quelli di istanza iniziano con a -. Per esempio:

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

Uscita: Età: 0 Numero di persone: 2

Un altro esempio è se si dispone di un metodo che si desidera che l'utente sia in grado di chiamare, a volte è utile trasformarlo in un metodo di classe. Ad esempio, se hai una classe chiamata MathFunctions, puoi farlo:

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

Quindi l'utente chiamerebbe:

[MathFunctions square:34];

senza mai dover istanziare la classe!

È inoltre possibile utilizzare le funzioni di classe per restituire oggetti rilasciati automaticamente, come quelli di NSArray

+ (NSArray *)arrayWithObject:(id)object

Questo prende un oggetto, lo inserisce in un array e restituisce una versione di array rilasciata automaticamente che non deve essere gestita dalla memoria, ottima per le matrici temperate e cosa no.

Spero che ora capisca quando e / o perché dovresti usare i metodi di classe !!


1
micmoo, potrei suggerirti di inserire "static int numberOfPeople = 0;" nel testo in codice formattato? Ero confuso fino a quando non l'ho notato sopra il codice di esempio. A parte questo, una risposta davvero concisa.
mobibob,

2
Perdonate la mia confusione da principiante, ma perché avete bisogno sia della variabile di istanza "age" che del metodo di istanza "age"? Getter e setter, ad esempio, non saranno creati con la variabile "age" con @synthetize?
selytch,

@selytch "age" dovrebbe essere definito come una proprietà per usare synthetize.
micah94,

36

Un metodo di istanza si applica a un'istanza della classe (cioè un oggetto) mentre un metodo di classe si applica alla classe stessa.

In C # un metodo di classe è contrassegnato come statico. I metodi e le proprietà non contrassegnati come statici sono metodi di istanza.

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}

1
Argh - mi dispiace, ho appena notato che questa era una domanda Obj-C. Spero che la mia risposta sia ancora valida, ma si prega di votare verso il basso o votare per eliminare.
Robert Horvick,

6
Nessun danno fatto. La prima parte della tua risposta è corretta come principio generale OOP e si applica sicuramente all'Obiettivo-C. Puoi aggiungere "goal-c" al tuo elenco di tag da ignorare se non vuoi vedere tali domande, anche se ogni partecipazione è sicuramente gradita. :-)
Quinn Taylor,

16

La risposta alla tua domanda non è specifica dell'obiettivo-c, tuttavia in diverse lingue, i metodi di classe possono essere chiamati metodi statici.

La differenza tra metodi di classe e metodi di istanza sono

Metodi di classe

  • Operare su variabili di classe (non possono accedere alle variabili di istanza)
  • Non richiede l'applicazione di un'istanza di un oggetto
  • A volte può essere un odore di codice (alcune persone che sono nuove a OOP usano come stampella per fare la programmazione strutturata in un ambiente OO)

Metodi di istanza

  • Operare su variabili di istanza e variabili di classe
  • Deve avere un oggetto istanziato su cui operare

I metodi di istanza possono operare su variabili di classe?
蘇健豪

16

Penso che il modo migliore per capirlo sia guardare alloce init. È stata questa spiegazione che mi ha permesso di capire le differenze.

Metodo di classe

Un metodo di classe viene applicato all'intera classe. Se controlli il allocmetodo, si tratta di un metodo di classe indicato dalla +dichiarazione precedente al metodo. È un metodo di classe perché viene applicato alla classe per creare un'istanza specifica di quella classe.

Metodo di istanza

Si utilizza un metodo di istanza per modificare un'istanza specifica di una classe che è unica per quell'istanza, piuttosto che per la classe nel suo insieme. initper esempio (indicato con una -prima della dichiarazione del metodo), è un metodo di istanza perché si stanno normalmente modificando le proprietà di quella classe dopo che è stata creata con alloc.

Esempio

NSString *myString = [NSString alloc];

Stai chiamando il metodo class allocper generare un'istanza di quella classe. Nota come il destinatario del messaggio sia una classe.

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

Stai modificando l'istanza di NSStringchiamata myStringimpostando alcune proprietà su quell'istanza. Notare come il destinatario del messaggio sia un'istanza (oggetto di classe NSString).


Cosa intendi con il metodo "alloc"? Puoi indicarmi un posto specifico nella documentazione? (modifica) -> ah, non importa, sì, nei documenti di NSObject si dice che in "Compiti" - developer.apple.com/library/ios/documentation/cocoa/reference/…
Ethan Parker

Non hai davvero bisogno di capire cosa fa veramente per afferrarlo, solo che viene applicato alla classe. In parole semplici: allocalloca memoria sufficiente per l'oggetto, initmodificherà ciò che è in quegli indirizzi di memoria per definire lo stato dell'oggetto. Non possiamo modificare un oggetto a meno che non ci sia uno spazio in cui modificarlo, quindi utilizziamo allocla classe che deciderà di darci quello spazio.
Adam Waite,

6

I metodi di classe vengono generalmente utilizzati per creare istanze di quella classe

Ad esempio, [NSString stringWithFormat:@"SomeParameter"];restituisce NSStringun'istanza con il parametro che le viene inviato. Quindi, poiché è un metodo Class che restituisce un oggetto del suo tipo, viene anche chiamato metodo di convenienza.


6

Quindi se lo capisco correttamente.

Un classmetodo non ha bisogno che tu assegni l'istanza di quell'oggetto per usarlo / elaborarlo. Un classmetodo è autonomo e può operare senza alcuna dipendenza dallo stato di alcun oggetto di quella classe. Un classmetodo dovrebbe allocare memoria per tutto il proprio lavoro e deallocare al termine, poiché nessuna istanza di quella classe sarà in grado di liberare memoria assegnata al metodo di classe in chiamate precedenti.

Un instancemetodo è esattamente l'opposto. Non è possibile chiamarlo se non si alloca un'istanza di quella classe. È come una classe normale che ha un costruttore e può avere un distruttore (che pulisce tutta la memoria allocata).

Nella maggior parte dei casi (a meno che tu non stia scrivendo una libreria riutilizzabile, non dovresti aver bisogno di una classvariabile.


1
Un caso ovvio in cui sono necessari metodi di classe è la creazione di istanze. Devi essere in grado di creare istanze senza averne ancora nessuna, altrimenti la prima istanza non potrebbe mai essere creata. Ecco perché + alloc è e deve essere un metodo di classe.
gnasher729,

4

I metodi delle istanze operano su istanze di classi (cioè "oggetti"). I metodi di classe sono associati alle classi (la maggior parte delle lingue usa la parola chiave staticper questi ragazzi).


3

Prendiamo ad esempio un gioco in cui vengono generate molte macchine .. ognuna appartiene alla classe CCar. Quando un'auto viene istanziata, effettua una chiamata a

[CCar registerCar:self]

Quindi la classe CCar, può fare un elenco di ogni CCar istanziato. Supponiamo che l'utente termini un livello e desideri rimuovere tutte le auto ... Puoi: 1- Andare attraverso un elenco di tutte le CCar create manualmente e fare whicheverCar.remove(); o 2- Aggiungere un metodo removeAllCars a CCar, che lo farà per te quando chiami [CCar removeAllCars]. ie allCars[n].remove();

O ad esempio, si consente all'utente di specificare una dimensione del carattere predefinita per l'intera app, che viene caricata e salvata all'avvio. Senza il metodo di classe, potresti dover fare qualcosa del genere

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

Con il metodo di classe, potresti cavartela [FontHandler getDefaultFontSize].

Per quanto riguarda la tua funzione removeVowels, troverai che linguaggi come C # in realtà hanno entrambi con determinati metodi come toLower o toUpper.

eg myString.removeVowels() e String.removeVowels(myString) (in ObjC che sarebbe [String removeVowels:myString]).

In questo caso l'istanza probabilmente chiama il metodo class, quindi entrambi sono disponibili. vale a dire

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

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

fondamentalmente, myString.toLower() chiama [String toLower:ownValue]

Non esiste una risposta definitiva, ma se hai voglia di inserire un metodo di classe migliorerebbe il tuo codice, provalo e tieni presente che un metodo di classe ti consentirà di utilizzare solo altri metodi / variabili di classe.


3

metodi di classe

sono metodi dichiarati statici. Il metodo può essere chiamato senza creare un'istanza della classe. I metodi di classe possono operare solo sui membri di classe e non sui membri di istanza poiché i metodi di classe non sono a conoscenza dei membri di istanza. I metodi di istanza della classe non possono essere richiamati dall'interno di un metodo di classe a meno che non vengano chiamati su un'istanza di quella classe.

Metodi di istanza

d'altra parte è necessario che esista un'istanza della classe prima di poter essere chiamata, quindi è necessario creare un'istanza di una classe utilizzando la nuova parola chiave. I metodi di istanza operano su istanze specifiche di classi. I metodi di istanza non sono dichiarati come statici.


Può anche essere creato con la parola chiave "alloc" non solo il "nuovo". Inoltre, Objective-C non richiede l'esistenza di un'istanza per chiamare un metodo di istanza, è possibile inviare messaggi a un puntatore null.
Elviss Strazdins l'

3

In Objective-C tutti i metodi iniziano con un carattere "-" o "+". Esempio:

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

+ (void) classMethod;
@end

I caratteri "+" e "-" specificano se un metodo è rispettivamente a class methodo a instance method.

La differenza sarebbe chiara se chiamiamo questi metodi. Qui i metodi sono dichiarati in MyClass.

instance method richiede un'istanza della classe:

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

All'interno di MyClassaltri metodi è possibile chiamare metodi di istanza di MyClassutilizzo self:

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

Ma, class methodsdeve essere chiamato sulla classe stessa:

[MyClass classMethod];

O:

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

Questo non funzionerà:

// Error
[myClass classMethod];
// Error
[self classMethod];

3

METODI DI CLASSE


Un metodo di classe in genere crea una nuova istanza della classe o recupera alcune proprietà globali della classe. I metodi di classe non funzionano su un'istanza o non hanno accesso alla variabile di istanza.


METODI DI ISTANZA


Un metodo di istanza opera su una particolare istanza della classe. Ad esempio, il metodo degli accessori implementato sono tutti i metodi di istanza. Li usi per impostare o ottenere le variabili di istanza di un particolare oggetto.


INVOCARE


Per invocare un metodo di istanza, si invia il messaggio a un'istanza della classe.

Per invocare un metodo di classe, si invia direttamente il messaggio alla classe.


Fonte: IOS - Objective-C - Metodi di classe e metodi di istanza


1

I metodi di classe non possono cambiare o conoscere il valore di qualsiasi variabile di istanza. Questo dovrebbe essere il criterio per sapere se un metodo di istanza può essere un metodo di classe.


-1 da me, perché puoi passare istanza al metodo class e sarà in grado di cambiare e conoscere i valori delle sue variabili.
Elviss Strazdins,

1

Ricorda anche che la stessa idea si applica alle variabili. Incontrerai termini come statico, membro, istanza, classe e così via quando si parla di variabili come per metodi / funzioni.

Sembra che il termine comune nella comunità di Obj-C sia ivar per esempio variabile, ma non sono ancora un ragazzo di Obj-C.


1

Un aggiornamento alle risposte di cui sopra, sono d'accordo che i metodi di istanza utilizzano un'istanza di una classe, mentre un metodo di classe può essere utilizzato solo con il nome della classe.

Non c'è più alcuna differenza tra il metodo di istanza e il metodo di classe dopo che il conteggio dei riferimenti automatico è diventato realtà in Objective-C.

Ad esempio [NS StringWithformat:..]un metodo di classe e [[NSString alloc] initwihtformat:..]un metodo di istanza, entrambi sono uguali dopo ARC


1

Nota: questo è solo in formato pseudo-codice

Metodo di classe

Quasi tutto ciò che deve fare è durante il tempo di compilazione . Non ha bisogno di alcun input dell'utente, né il suo calcolo si basa su un'istanza. Tutto al riguardo si basa sulla classe / progetto — che è unico, cioè non hai più progetti per una classe. Puoi avere diverse variazioni durante il tempo di compilazione? No, quindi la classe è unica e quindi, indipendentemente dal numero di volte in cui si chiama un metodo di classe, il puntatore che lo punta sarebbe lo stesso.

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

Metodo di istanza

Al contrario, il metodo di istanza si verifica durante il runtime, poiché è solo allora che è stata creata un'istanza di qualcosa che può variare ad ogni istanza.

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.

Se provieni da altre lingue I metodi statici sono gli stessi dei metodi di classe.
Se vieni da Swift, i metodi di tipo sono gli stessi dei metodi di classe.


0

Aggiungendo alle risposte sopra

Il metodo di classe funzionerà in classe, lo useremo per scopi generali dove come + stringWithFormat, dimensione della classe e, soprattutto, per init etc

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

Il metodo Instance funzionerà su un'istanza di una classe non su una classe come se avessimo due persone e vogliamo conoscere il bilancio di ciascuna separatamente qui, è necessario utilizzare il metodo di istanza. Perché non restituirà una risposta generale. es. come determinare il conteggio di NSSArray ecc.

[johnson getAccountBalance];
[ankit getAccountBalance];
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.