Jaka jest różnica między metodami klasy i instancji?

448

Jaka jest różnica między metodą klasy a metodą instancji?

Czy metody instancji są akcesorami (modułami pobierającymi i ustawiającymi), podczas gdy metody klasowe to właściwie wszystko inne?

Oddany
źródło

Odpowiedzi:

673

Podobnie jak większość innych odpowiedzi, metody instancji wykorzystują instancję klasy, podczas gdy metoda klasy może być używana tylko z nazwą klasy. W Celu C są one zdefiniowane w następujący sposób:

@interface MyClass : NSObject

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

@end

Można je następnie wykorzystać w następujący sposób:

[MyClass aClassMethod];

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

Niektóre przykłady świata rzeczywistego z metod klasy są metody wygoda na wiele klas, takich jak Foundation NSString„s +stringWithFormat:lub NSArray” s +arrayWithArray:. Metoda przykład byłoby NSArray„S -countmetodą.

Cory Kilger
źródło
7
Dobra odpowiedź. Warto również zauważyć, że zobaczysz szczególną skrótową notację opisującą metody. Na przykład + [NSString stringWithFormat:] to metoda klasy + stringWithFormat: na NSString; - [NSArray objectAtIndex:] to metoda instancji. Metody z wieloma częściami selektora są zapisywane jak - [NSMutableDictionary setObject: forKey:] itd. Często można zobaczyć tę notację w odpowiedziach Cocoa, dokumentacji i Xcode.
Quinn Taylor
149
Dodałbym, że metoda klasowa jest nazywana metodą „statyczną” w wielu innych językach. Aby odpowiedzieć na pierwotne pytanie, akcesory są metodami instancji, ponieważ ustawiają i uzyskują stan konkretnej instancji. W powyższym przykładzie liczba NSArray zwraca liczbę obiektów w określonej instancji.
Brian Pan
2
„podczas gdy metoda klasy może być używana tylko z nazwą klasy.” lub obiekt klasy
użytkownik102008
2
Przepraszam za moje podekscytowanie ... ale właśnie poznałem różnicę i jej potencjał. klasowe metody rockowe, podobnie jak klasy singletonowe! ufff zakochałem się! <3
Pavan
2
@BrianPan metody statyczne i klasy nie są takie same. Są podobne, ale dlatego, że mają różne nazwy, działają inaczej. Na przykład metod statycznych nie można zastąpić.
Sulthan
190

Wszystkie szczegóły techniczne zostały ładnie ujęte w innych odpowiedziach. Chcę tylko podzielić się prostą analogią, która moim zdaniem dobrze ilustruje różnicę między klasą a instancją:

wprowadź opis zdjęcia tutaj

Klasa jest jak plan domu: Masz tylko jeden plan i (zazwyczaj) nie można zrobić, że wiele z samym planem.

wprowadź opis zdjęcia tutaj

Przykład (lub obiekt ) jest rzeczywistą dom , który budować w oparciu o plan: Można budować wiele domów z tego samego planu. Następnie możesz pomalować ściany innym kolorem w każdym domu, tak jak możesz niezależnie zmieniać właściwości każdej instancji klasy bez wpływu na inne instancje.

Johannes Fahrenkrug
źródło
6
@JohannesFahrenkrug Ładnie wyjaśnił tutaj pojęcie klasy i obiektu. Nie jest to rzeczywiste pytanie difference between class method and an instance method ;
Shekhu,
1
Doskonałe wyjaśnienie klasy a wystąpienie klasy. Klasy są dziwną koncepcją dla początkujących, co wyjaśnia to w najbardziej fundamentalny sposób.
Alex McPherson
1
@JohannesFahrenkrug naprawdę dobre wytłumaczenie, które skłoniło mnie do zastanowienia się, w jaki sposób oba są różne i kiedy używać obu
ChenSmile
1
Takie wspaniałe wyjaśnienie :)
Praveenkumar
1
Dobra analogia. Proszę, niech ktoś da temu facetowi zapas pizzy na rok.
GeneCode
102

Podobnie jak inne odpowiedzi, metody instancji działają na obiekcie i mają dostęp do zmiennych instancji, podczas gdy metoda klasy działa na klasie jako całości i nie ma dostępu do zmiennych konkretnej instancji (chyba że instancja zostanie przekazana jako parametr).

Dobrym przykładem metody klasowej jest metoda typu przeciwnego, która zwraca całkowitą liczbę instancji klasy. Metody klas zaczynają się od a +, podczas gdy metody instancji zaczynają się od -. Na przykład:

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

Wyjście: Wiek: 0 Liczba osób: 2

Innym przykładem jest metoda, którą użytkownik może wywoływać, czasem dobrze jest uczynić ją metodą klasową. Na przykład, jeśli masz klasę o nazwie MathFunctions, możesz to zrobić:

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

Zatem użytkownik zadzwoni:

[MathFunctions square:34];

bez konieczności tworzenia klasy!

Możesz także użyć funkcji klasy do zwracania automatycznie wydanych obiektów, takich jak NSArray

+ (NSArray *)arrayWithObject:(id)object

To pobiera obiekt, umieszcza go w tablicy i zwraca automatycznie wydaną wersję tablicy, która nie musi być zarządzana pamięcią, co jest idealne dla tablic temperamentalnych i nie tylko.

Mam nadzieję, że teraz rozumiesz, kiedy i / lub dlaczego powinieneś używać metod klasowych !!

micmoo
źródło
1
micmoo, proponuję wstawić „static int numberOfPeople = 0;” w tekście sformatowanym kodem? Byłem zdezorientowany, dopóki nie zauważyłem go powyżej przykładowego kodu. Poza tym naprawdę zwięzła odpowiedź.
mobibob
2
Przepraszam za zamieszanie dla początkujących, ale dlaczego potrzebujesz zarówno zmiennej instancji „wiek”, jak i metody instancji „wiek”? Czy getter i setter na przykład zmienna „age” nie będą tworzone za pomocą @synthetize?
selytch
@selytch „wiek” musiałby zostać zdefiniowany jako właściwość, aby można było użyć syntezatora.
micah94
36

Metoda instancji ma zastosowanie do instancji klasy (tj. Obiektu), podczas gdy metoda klasy ma zastosowanie do samej klasy.

W języku C # metoda klasy jest oznaczona statycznie. Metody i właściwości nieoznaczone statycznie są metodami instancji.

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}
Robert Horvick
źródło
1
Argh - przepraszam, właśnie zauważyłem, że to pytanie Obj-C. Mam nadzieję, że moja odpowiedź nadal obowiązuje, ale proszę głosować w dół lub głosować, aby usunąć.
Robert Horvick
6
Żadna krzywda. Pierwsza część twojej odpowiedzi jest poprawna jako ogólna zasada OOP i zdecydowanie odnosi się do Celu-C. Możesz dodać „goal-c” do swojej listy tagów, aby je zignorować, jeśli nie chcesz widzieć takich pytań, chociaż jakikolwiek udział jest z pewnością mile widziany. :-)
Quinn Taylor
16

Odpowiedź na twoje pytanie nie jest specyficzna dla celu-c, jednak w różnych językach metody klasowe można nazwać metodami statycznymi.

Różnice między metodami klasowymi a metodami instancji są następujące

Metody klasowe

  • Działaj na zmiennych klasy (nie mają dostępu do zmiennych instancji)
  • Nie wymaga zastosowania instancji obiektu do zastosowania
  • Czasami może być zapach kodu (niektóre osoby, które są nowicjuszami w OOP, używają jako narzędzia do programowania strukturalnego w środowisku OO)

Metody instancji

  • Działaj na zmiennych instancji i zmiennych klas
  • Musi mieć zaimplementowany obiekt do działania
hhafez
źródło
Metody instancji mogą działać na zmiennych klasowych?
蘇健豪
16

Myślę, że najlepszym sposobem na zrozumienie tego jest spojrzenie na alloci init. To wyjaśnienie pozwoliło mi zrozumieć różnice.

Metoda klasowa

Metoda klasy jest stosowana do całej klasy. Jeśli alloczaznaczysz metodę, jest to metoda klasy oznaczona przez+ przed deklaracją metody. Jest to metoda klasowa, ponieważ jest stosowana do klasy w celu utworzenia określonego wystąpienia tej klasy.

Metoda wystąpienia

Metoda instancji służy do modyfikowania określonej instancji klasy, która jest unikalna dla tej instancji, a nie dla klasy jako całości. initna przykład (oznaczony -przed deklaracją metody), jest metodą instancji, ponieważ zwykle modyfikuje się właściwości tej klasy po jej utworzeniu alloc.

Przykład

NSString *myString = [NSString alloc];

Wywołujesz metodę klasy alloc, aby wygenerować instancję tej klasy. Zauważ, że odbiorcą wiadomości jest klasa.

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

Zmieniasz instancję NSStringwywoływanej myStringprzez ustawienie niektórych właściwości dla tej instancji. Zwróć uwagę, w jaki sposób odbiorca wiadomości jest instancją (obiektem klasy NSString).

Adam Waite
źródło
Co rozumiesz przez sprawdzenie metody „przydzielania”? Czy możesz wskazać mi określone miejsce w dokumentacji? (edytuj) -> ahh nieważne, tak w dokumentach NSObject mówi się, że pod „Zadaniami” - developer.apple.com/library/ios/documentation/cocoa/reference/…
Ethan Parker
Naprawdę nie musisz rozumieć, co to tak naprawdę jest, aby to zrozumieć, wystarczy, że zostanie zastosowane do klasy. Mówiąc prosto: allocprzydziela wystarczającą ilość pamięci dla obiektu, initzmodyfikuje zawartość tych adresów pamięci, aby zdefiniować stan obiektu. Nie możemy modyfikować obiektu, chyba że będzie w nim miejsce do modyfikacji, więc korzystamy allocz klasy, która zdecyduje się dać nam tę przestrzeń.
Adam Waite,
6

Metody klasy są zwykle używane do tworzenia instancji tej klasy

Na przykład [NSString stringWithFormat:@"SomeParameter"];zwraca NSStringinstancję z parametrem, który jest do niej wysyłany. Dlatego, ponieważ jest to metoda klasy, która zwraca obiekt tego typu, jest również nazywana metodą wygody.

iosrookie
źródło
6

Więc jeśli dobrze to rozumiem.

classMetoda nie musisz przeznaczyć instancji tego obiektu do użytkowania / przetworzyć. classMetoda jest autonomiczny i może pracować bez uzależnienia od stanu dowolnego obiektu tej klasy. classOczekuje się metoda przydzielić pamięci dla całej swojej pracy i zwalnianie kiedy zrobić, ponieważ nie instancja tej klasy będą mogły uwolnić żadnej pamięci przydzielonej w poprzednich wywołań metody klasy.

instanceMetoda jest dokładnie odwrotnie. Nie możesz do niego zadzwonić, dopóki nie przydzielisz instancji tej klasy. To jest jak normalna klasa, która ma konstruktor i może mieć destruktor (który czyści całą przydzieloną pamięć).

Najprawdopodobniej (chyba że piszesz bibliotekę wielokrotnego użytku, nie potrzebujesz classzmiennej).

Siddharth
źródło
1
Oczywistym przypadkiem, w którym potrzebujesz metod klasowych, jest tworzenie instancji. Musisz mieć możliwość tworzenia instancji jeszcze bez żadnych instancji, w przeciwnym razie pierwsza instancja nigdy nie zostanie utworzona. Dlatego + przydział jest i musi być metodą klasową.
gnasher729
4

Metody instancji działają na instancjach klas (tj. „Obiektach”). Metody klasowe są powiązane z klasami (większość języków używa tych słów kluczowych static).

zirytowany
źródło
3

Weźmy na przykład grę, w której odradza się wiele samochodów. Każdy z nich należy do klasy CCar. Po utworzeniu instancji samochodu następuje połączenie z

[CCar registerCar:self]

Tak więc klasa CCar może tworzyć listę wszystkich instancji CCar. Powiedzmy, że użytkownik kończy poziom i chce usunąć wszystkie samochody ... możesz: 1 - Przejrzeć listę każdego CCar utworzonego ręcznie i zrobić whicheverCar.remove(); lub 2 - Dodać metodę removeAllCars do CCar, która to zrobi dla ciebie, gdy zadzwonisz [CCar removeAllCars]. To znaczy allCars[n].remove();

Lub na przykład pozwalasz użytkownikowi określić domyślny rozmiar czcionki dla całej aplikacji, która jest ładowana i zapisywana podczas uruchamiania. Bez metody klasy może być konieczne wykonanie czegoś takiego

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

Dzięki metodzie klasy możesz uciec [FontHandler getDefaultFontSize].

Jeśli chodzi o funkcję removeVowels, przekonasz się, że języki takie jak C # faktycznie mają obie z pewnymi metodami, takimi jak toLower lub toUpper.

np. myString.removeVowels() i String.removeVowels(myString) (w ObjC byłoby [String removeVowels:myString]).

W takim przypadku instancja prawdopodobnie wywołuje metodę klasy, więc obie są dostępne. to znaczy

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

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

w zasadzie myString.toLower() połączenia [String toLower:ownValue]

Nie ma ostatecznej odpowiedzi, ale jeśli masz ochotę wepchnąć metodę klasową, poprawiłbyś swój kod, wypróbuj go i pamiętaj, że metoda klasowa pozwoli ci tylko na użycie innych metod / zmiennych klasowych.

sierp sierpowy
źródło
3

metody klasowe

są metodami zadeklarowanymi jako statyczne. Metodę można wywołać bez tworzenia instancji klasy. Metody klasy mogą działać tylko na elementach klasy, a nie na elementach instancji, ponieważ metody klasy nie są świadome elementów instancji. Metod instancji klasy nie można również wywoływać z metody klasy, chyba że są one wywoływane w instancji tej klasy.

Metody instancji

z drugiej strony wymaga wystąpienia instancji klasy, zanim będzie można ją wywołać, dlatego należy utworzyć instancję klasy przy użyciu nowego słowa kluczowego. Metody instancji działają na określonych instancjach klas. Metody instancji nie są deklarowane jako statyczne.

iCrazyDev
źródło
Można go również utworzyć za pomocą słowa kluczowego „przydzielić”, a nie tylko „nowego”. Ponadto Objective-C nie wymaga istnienia instancji w celu wywołania metody instancji, można wysyłać wiadomości do wskaźnika zerowego.
Elviss Strazdins,
3

W Objective-C wszystkie metody zaczynają się od znaku „-” lub „+”. Przykład:

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

+ (void) classMethod;
@end

Znak „+” i „-” znaków określić, czy dana metoda jest class methodalbo instance methododpowiednio.

Różnica byłaby wyraźna, gdybyśmy wywołali te metody. Tutaj metody są zadeklarowane w MyClass.

instance method wymagają wystąpienia klasy:

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

Wewnątrz MyClassinne metody mogą wywoływać metody instancji MyClassprzy użyciu self:

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

Ale class methodsnależy wywołać samą klasę:

[MyClass classMethod];

Lub:

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

To nie zadziała:

// Error
[myClass classMethod];
// Error
[self classMethod];
Tulon
źródło
3

METODY KLASOWE


Metoda klasy zazwyczaj tworzy nową instancję klasy lub pobiera niektóre globalne właściwości klasy. Metody klasy nie działają na instancji ani nie mają dostępu do zmiennej instancji.


METODY INSTANCJI


Metoda instancji działa na konkretnej instancji klasy. Na przykład zaimplementowana metoda akcesorów to wszystkie metody instancji. Używasz ich do ustawiania lub pobierania zmiennych instancji określonego obiektu.


ODWOŁAĆ SIĘ


Aby wywołać metodę instancji, wysyłasz wiadomość do instancji klasy.

Aby wywołać metodę klasy, wyślij wiadomość bezpośrednio do klasy.


Źródło: IOS - Objective-C - Metody klasowe i metody instancji

Nam N. HUYNH
źródło
1

Metody klasy nie mogą zmieniać ani znać wartości żadnej zmiennej instancji. To powinny być kryteria pozwalające stwierdzić, czy metoda instancji może być metodą klasy.

Deepee
źródło
-1 ode mnie, ponieważ możesz przekazać instancję do metody klasy, która będzie mogła zmieniać i znać wartości zmiennych.
Elviss Strazdins,
1

Pamiętaj również, że ten sam pomysł dotyczy zmiennych. Podczas mówienia o zmiennych takich samych, jak w przypadku metod / funkcji, można spotkać terminy takie jak static, member, instance, class i tak dalej.

Wydaje się, że powszechnym terminem w społeczności Obj-C jest na przykład zmienna ivar, ale jeszcze nie jestem facetem Obj-C.

Half_Duplex
źródło
1

Aktualizacja powyższych odpowiedzi. Zgadzam się, że metody instancji używają instancji klasy, podczas gdy metody klasy można używać tylko z nazwą klasy.

Nie ma już żadnej różnicy między metodą instancji i metodą klasy po automatycznym zliczaniu referencji w Objective-C.

Na przykład [NS StringWithformat:..]metoda klasy i [[NSString alloc] initwihtformat:..]metoda instancji oba są takie same po ARC

użytkownik1292809
źródło
1

Uwaga: Jest to tylko w formacie pseudokodu

Metoda klasowa

Prawie wszystko, co musi zrobić, to czas kompilacji . Nie wymaga żadnych danych wejściowych od użytkownika, a jego obliczenia nie są oparte na instancji. Wszystko w tym opiera się na klasie / schemacie — co jest unikalne, tzn. Nie masz wielu schematów dla jednej klasy. Czy możesz mieć różne odmiany w czasie kompilacji? Nie, dlatego klasa jest unikalna, więc niezależnie od tego, ile razy wywołasz metodę klasową, wskaźnik do niej będzie taki sam.

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

Metoda wystąpienia

Wręcz przeciwnie, metoda występuje w czasie wykonywania, ponieważ dopiero wtedy utworzono instancję czegoś, co może zmieniać się przy każdej instancji.

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.

Jeśli pochodzisz z innych języków, metody statyczne są takie same jak metody klasowe.
Jeśli pochodzisz z Swift, metody typowania są takie same jak metody klasowe.

miód
źródło
0

Dodanie do powyższych odpowiedzi

Metoda klasy będzie działać na klasie, użyjemy jej do ogólnego celu, gdzie jak + stringWithFormat, rozmiar klasy i co najważniejsze dla init itp

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

Metoda instancji będzie działać na instancji klasy, a nie na klasie, tak jak mamy dwie osoby i chcemy poznać bilans każdej z nich osobno, tutaj musimy użyć metody instancji. Ponieważ nie zwróci ogólnej odpowiedzi. np. jak określić liczbę NSSArray itp.

[johnson getAccountBalance];
[ankit getAccountBalance];
Anargit garg
źródło