Sınıf ve örnek yöntemleri arasındaki fark nedir?


Yanıtlar:


673

Diğer yanıtların çoğunun söylediği gibi, örnek yöntemleri sınıfın bir örneğini kullanırken, sınıf yöntemi yalnızca sınıf adıyla kullanılabilir. Amaç-C'de bu şekilde tanımlanırlar:

@interface MyClass : NSObject

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

@end

Daha sonra şu şekilde kullanılabilirler:

[MyClass aClassMethod];

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

Sınıf yöntemlerinden bazı gerçek dünya örnekleri NSString's ' +stringWithFormat:veya NSArray's' gibi birçok Foundation sınıfındaki kolaylık yöntemleridir +arrayWithArray:. Örnek, yöntem olacaktır NSArraybireyin -countyöntemi.


7
İyi cevap. Yöntemleri tanımlamak için belirli bir steno gösterimi göreceğinizi de belirtmek gerekir. Örneğin, + [NSString stringWithFormat:], + stringWithFormat: on NSString sınıf yöntemidir; - [NSArray objectAtIndex:] bir örnek yöntemidir. Birden çok seçici parça içeren yöntemler şöyle yazılır - [NSMutableDictionary setObject: forKey:] vb. Bu gösterimi genellikle Kakao yanıtlarında, belgelerinde ve Xcode'da görürsünüz.
Quinn Taylor

149
Bir sınıf yöntemi diğer birçok dilde "statik" yöntem denir eklemek istiyorum. Ve orijinal soruyu cevaplamak için, erişimciler örnek bir yöntemdir, çünkü belirli bir örneğin durumunu ayarlayıp alırlar. Yukarıdaki örnekte, NSArray sayısı belirli bir örnekteki nesne sayısını döndürür.
Brian Pan

2
"bir sınıf yöntemi ise sadece sınıf adıyla kullanılabilir." ya da sınıf nesnesi
user102008

2
Heyecanım için özür dilerim ... ama sadece farkı ve potansiyelini öğrendim. sınıf yöntemleri rock ve singleton sınıfları da! ufff Aşık oldum! <3
Pavan

2
@BrianPan statik ve sınıf yöntemleri aynı değildir. Benzerler, ancak farklı isimlendirilmelerinin nedeni, farklı şekilde çalışmalarıdır. Örneğin, statik yöntemler geçersiz kılınamaz.
Sulthan

190

Tüm teknik detaylar diğer cevaplarda iyi bir şekilde ele alınmıştır. Ben sadece bir sınıf ve bir örnek arasındaki farkı güzelce gösteren basit bir benzetmeyi paylaşmak istiyorum:

resim açıklamasını buraya girin

Bir sınıf gibidir planı bir evin: Yalnızca bir plan var ve (genellikle) tek başına planı ile bu kadar yapamaz.

resim açıklamasını buraya girin

Bir örnek (veya nesne ), plana dayanarak inşa ettiğiniz gerçek evdir : Aynı plandan çok sayıda ev inşa edebilirsiniz. Daha sonra, diğer sınıfları etkilemeden bir sınıfın her örneğinin özelliklerini bağımsız olarak değiştirebileceğiniz gibi, duvarların her birinde farklı bir renk boyayabilirsiniz.


6
@JohannesFahrenkrug Sınıf ve nesne kavramını güzelce açıkladı. Asıl soru bunun için değil difference between class method and an instance method ;
Shekhu

1
Sınıf ve Sınıf Örneği hakkında mükemmel açıklama. Sınıflar yeni başlayanlar için garip bir kavramdır ve bu onu en temel şekilde açıklar.
Alex McPherson

1
Gerçekten boths diff r nasıl düşünmek beni yapılmış ve ne zaman ikisini de kullanmak iyi bir açıklama, @JohannesFahrenkrug
ChenSmile

1
Böyle harika bir açıklama :)
Praveenkumar

1
İyi benzetme. Lütfen birisi bu adama bir sene pizza veriyor.
GeneCode

102

Diğer yanıtların söylediği gibi, örnek yöntemleri bir nesne üzerinde çalışır ve örnek değişkenlerine erişirken, bir sınıf yöntemi bir sınıfta bir bütün olarak çalışır ve belirli bir örneğin değişkenlerine erişemez ((örneği bir parametre).

Sınıf yöntemine iyi bir örnek, bir sınıfın toplam örnek sayısını döndüren sayaç tipi bir yöntemdir. Sınıf yöntemleri a ile başlar +, örnek olanlar ise bir ile başlar -. Örneğin:

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

Çıktı: Yaş: 0 Kişi sayısı: 2

Başka bir örnek, kullanıcının arayabilmesini istediğiniz bir yönteminiz varsa, bazen bunu bir sınıf yöntemi yapmak iyi olur. Örneğin, MathFunctions adında bir sınıfınız varsa, bunu yapabilirsiniz:

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

Böylece kullanıcı şunu arar:

[MathFunctions square:34];

hiç bir zaman dersi başlatmak zorunda kalmadan!

NSArray'ınki gibi otomatik olarak yayınlanan nesneleri döndürmek için sınıf işlevlerini de kullanabilirsiniz

+ (NSArray *)arrayWithObject:(id)object

Bu, bir nesneyi alır, bir diziye yerleştirir ve dizinin bellek tarafından yönetilmesi gerekmeyen, geçici diziler için harika olan ve olmayan bir otomatik olarak yayınlanmış sürümünü döndürür.

Umarım şimdi sınıf yöntemlerini ne zaman ve / veya neden kullanmanız gerektiğini anlarsınız !!


1
micmoo, "static int numberOfPeople = 0;" kod biçimlendirilmiş metin? Örnek kodun üstünde fark edene kadar kafam karıştı. Bunun dışında gerçekten özlü bir cevap.
mobibob

2
Acemi karışıklığımı affedin, ama neden hem örnek değişkeni "age" hem de örnek yöntemi "age" ye ihtiyacınız var? Synthetize ile alıcı ve ayarlayıcı örneğin "yaş" oluşturulmaz mı?
selytch

@selytch "age", synthetize özelliğini kullanmak için bir özellik olarak tanımlanmalıdır.
micah94

36

Bir örnek yöntemi sınıfın bir örneğine (yani bir nesneye) uygulanırken sınıf yöntemi sınıfın kendisine uygulanır.

C # 'da bir sınıf yöntemi statik olarak işaretlenmiştir. Statik olarak işaretlenmemiş yöntemler ve özellikler, örnek yöntemlerdir.

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

1
Argh - üzgünüm, bunun bir Obj-C sorusu olduğunu fark ettim. Umarım cevabım hala geçerlidir ama lütfen oy verin veya silmek için oy verin.
Robert Horvick

6
Hiçbir zararı olmadı. Cevabınızın ilk kısmı genel bir OOP prensibi olarak doğrudur ve kesinlikle Objective-C için geçerlidir. Bu tür soruları görmek istemiyorsanız, yok saymak için etiket listenize "objektif-c" ekleyebilirsiniz, ancak herhangi bir katılım kesinlikle kabul edilir. :-)
Quinn Taylor

16

Sorunuzun cevabı objektif-c'ye özgü değildir, ancak farklı dillerde Sınıf yöntemleri statik yöntemler olarak adlandırılabilir.

Sınıf yöntemleri ve örnek yöntemler arasındaki fark

Sınıf yöntemleri

  • Sınıf değişkenleri üzerinde işlem (örnek değişkenlerine erişemezler)
  • Bir nesnenin uygulanması için somutlaştırılmasına gerek yok
  • Bazen bir kod kokusu olabilir (OOP'de yeni olan bazı insanlar bir OO ortamında Yapısal Programlama yapmak için bir koltuk değneği olarak kullanır)

Örnek yöntemleri

  • Örnek değişkenleri ve sınıf değişkenleri üzerinde işlem yapma
  • Üzerinde işlem yapmak için somutlaştırılmış bir nesne olmalı

Örnek değişkenler sınıf değişkenleri üzerinde çalışabilir mi?
蘇健豪

16

Bence bunu anlamanın en iyi yolu allocve init. Farklılıkları anlamama izin veren bu açıklama oldu.

Sınıf Yöntemi

Sınıf yöntemi bir bütün olarak sınıfa uygulanır. allocYöntemi kontrol ederseniz , bu yöntem +yöntem bildiriminden önce belirtilen bir sınıf yöntemidir . Bu bir sınıf yöntemidir, çünkü o sınıfın belirli bir örneğini yapmak için sınıfa uygulanır.

Örnek Yöntemi

Bir sınıfın bir bütün olarak değil, o örneğe özgü olan belirli bir sınıf örneğini değiştirmek için bir instance yöntemi kullanırsınız. initörneğin ( -yöntem bildiriminden önce bir ile belirtilir ), bir örnek yöntemdir, çünkü normalde sınıfın oluşturulduktan sonra özelliklerini değiştirirsiniz alloc.

Misal

NSString *myString = [NSString alloc];

Bu sınıfın allocbir örneğini oluşturmak için class yöntemini çağırıyorsunuz . Mesajın alıcısının nasıl bir sınıf olduğuna dikkat edin.

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

Sen örneğini değiştiriyorsanız NSStringdenilen myStringo örneğe bazı özelliklerini ayarlayarak. İletinin alıcısının bir örnek (sınıf nesnesi NSString) olduğuna dikkat edin .


"Tahsis" yöntemini kontrol etmekle ne demek istiyorsun? Beni belgelerde belirli bir yere yönlendirebilir misiniz? (değiştir) -> ahh nevermind, evet NSObject belgelerinde "Görevler" altında diyor - developer.apple.com/library/ios/documentation/cocoa/reference/…
Ethan Parker

Bunu kavramak için gerçekten ne yaptığını anlamanız gerekmez, sadece sınıfa uygulanır. Basitçe söylemek gerekirse: allocnesne için yeterli bellek ayırır, nesnenin initdurumunu tanımlamak için bu bellek adreslerindeki bilgileri değiştirir. İçinde değiştirilecek bir alan olmadığı sürece bir nesneyi değiştiremeyiz, bu yüzden allocsınıfta bize bu alanı vermeye karar vereceğiz.
Adam Waite

6

Sınıf yöntemleri genellikle bu sınıfın örneklerini oluşturmak için kullanılır

Örneğin, kendisine gönderilen parametreye sahip [NSString stringWithFormat:@"SomeParameter"];bir NSStringörnek döndürür . Bu nedenle, kendi türündeki bir nesneyi döndüren bir Class yöntemi olduğundan, buna kolaylık yöntemi de denir.


6

Eğer doğru anlarsam.

Bir classyöntem, onu kullanmak / işlemek için o nesnenin örneğini tahsis etmenizi gerektirmez. Bir classyöntem bağımsızdır ve o sınıfın herhangi bir nesnesinin durumuna bağımlı olmadan çalışabilir. Bir classyöntemin kendi çalışması için bellek ayırması ve bittiğinde dağıtması beklenir, çünkü bu sınıfın hiçbir örneği sınıf yöntemine yapılan önceki çağrılarda ayrılan belleği serbest bırakamaz.

Bir instanceyöntem tam tersidir. Söz konusu sınıfın bir örneğini ayırmadığınız sürece arayamazsınız. Bu, bir yapıcıya sahip olan ve bir yıkıcıya sahip olabilen (tahsis edilen tüm belleği temizleyen) normal bir sınıf gibidir.

Çoğu olasılıkta (yeniden kullanılabilir bir kitaplık yazmıyorsanız, bir classdeğişkene ihtiyacınız olmamalıdır .


1
Sınıf yöntemlerine ihtiyaç duyduğunuz bariz bir örnek, örneklerin oluşturulmasıdır. Henüz herhangi bir örneğiniz olmadan örnekler oluşturabilmeniz gerekir, aksi takdirde ilk örnek asla oluşturulamaz. Bu yüzden + tahsis bir sınıf metodudur ve olmalıdır.
gnasher729

4

Eşgörünüm yöntemleri sınıf örnekleri (yani, "nesneler") üzerinde çalışır. Sınıf yöntemleri sınıflarla ilişkilidir (çoğu dil staticbu çocuklar için anahtar kelimeyi kullanır ).


3

Örneğin, çok sayıda arabanın üretildiği bir oyunu ele alalım .. her biri CCar sınıfına aittir. Bir araba başlatıldığında,

[CCar registerCar:self]

Böylece CCar sınıfı, somutlaştırılan her CCar'ın bir listesini yapabilir. Kullanıcının bir düzeyi bitirdiğini ve tüm arabaları kaldırmak istediğini varsayalım ... Şunları yapabilirsiniz: 1- Manuel olarak oluşturduğunuz her CCar'ın bir listesini gözden geçirin ve yapın whicheverCar.remove(); veya 2- CCar'a bunu yapacak bir removeAllCars yöntemi ekleyin [CCar removeAllCars] dediğinizde sizin için. yani allCars[n].remove();

Örneğin, kullanıcının başlangıçta yüklenen ve kaydedilen tüm uygulama için varsayılan bir yazı tipi boyutu belirlemesine izin verirsiniz. Sınıf yöntemi olmadan, şöyle bir şey yapmanız gerekebilir

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

Sınıf yöntemi ile, kurtulabilirsiniz [FontHandler getDefaultFontSize].

RemoveVowels işlevinize gelince, C # gibi dillerin aslında her ikisinde de toLower veya toUpper gibi bazı yöntemlere sahip olduğunu göreceksiniz.

örneğin myString.removeVowels() ve String.removeVowels(myString) (ObjC'de [String removeVowels:myString]).

Bu durumda örnek muhtemelen sınıf yöntemini çağırır, bu nedenle her ikisi de kullanılabilir. yani

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

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

temel olarak, myString.toLower() aramalar [String toLower:ownValue]

Kesin bir cevap yoktur, ancak bir sınıf yöntemini itmek istiyorsanız kodunuzu geliştirir, bir şans verir ve bir sınıf yönteminin yalnızca diğer sınıf yöntemlerini / değişkenlerini kullanmanıza izin vereceğini unutmayın.


3

sınıf yöntemleri

statik olarak bildirilen yöntemlerdir. Yöntem, sınıfın bir örneği oluşturulmadan çağrılabilir. Sınıf yöntemleri yalnızca sınıf üyeleri üzerinde çalışabilir, sınıf üyeleri örnek üyelerinden habersiz olduğu için sınıf üyeleri üzerinde çalışamaz. Sınıfın örnek yöntemleri, söz konusu sınıfın bir örneğinde çağrılmadığı sürece, sınıf yönteminden de çağrılamaz.

Örnek yöntemleri

Öte yandan, çağrılmadan önce sınıfın bir örneğinin var olmasını gerektirir, bu nedenle yeni anahtar sözcük kullanılarak bir sınıf örneğinin oluşturulması gerekir. Örnek yöntemleri, sınıfların belirli örneklerinde çalışır. Örnek yöntemleri statik olarak bildirilmez.


Yalnızca "yeni" değil, "ayır" anahtar kelimesiyle de oluşturulabilir. Ayrıca, Objective-C bir örnek yöntemini çağırmak için bir örnek var olmasını talep etmez, boş bir işaretçiye mesaj gönderebilirsiniz.
Elviss Strazdins

3

Objective-C'de tüm yöntemler "-" veya "+" karakteriyle başlar. Misal:

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

+ (void) classMethod;
@end

"+" Ve "-" karakterleri, bir yöntemin sırasıyla bir class methodveya bir olup olmadığını belirtir instance method.

Bu yöntemleri çağırırsak fark açık olacaktır. Burada yöntemler belirtilir MyClass.

instance method sınıfın bir örneğini gerektirir:

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

MyClassDiğer yöntemlerin içinde örnek MyClasskullanma yöntemlerini çağırabilir self:

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

Ancak, class methodssınıfın kendisinde çağrılmalıdır:

[MyClass classMethod];

Veya:

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

Bu işe yaramaz:

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

3

SINIF YÖNTEMLERİ


Bir sınıf yöntemi tipik olarak ya sınıfın yeni bir örneğini oluşturur ya da sınıfın bazı genel özelliklerini alır. Sınıf yöntemleri bir örnek üzerinde çalışmaz veya örnek değişkenine erişimi yoktur.


ANLIK YÖNTEMLERİ


Bir örnek yöntemi, sınıfın belirli bir örneğinde çalışır. Örneğin, uyguladığınız erişimci yöntemi, tüm örnek yöntemleridir. Belirli bir nesnenin örnek değişkenlerini ayarlamak veya almak için bunları kullanırsınız.


ÇAĞIRMAK


Bir örnek yöntemini çağırmak için iletiyi sınıfın bir örneğine gönderirsiniz.

Bir sınıf yöntemini çağırmak için, mesajı doğrudan sınıfa gönderirsiniz.


Kaynak: IOS - Objective-C - Sınıf Yöntemleri ve Örnek Yöntemleri


1

Sınıf yöntemleri herhangi bir örnek değişkeninin değerini değiştiremez veya bilemez. Bir örnek yönteminin bir sınıf yöntemi olup olmadığını bilmek için kriterler bu olmalıdır.


Benden -1, çünkü sınıf yöntemine örnek iletebilirsiniz ve değişkenlerin değerlerini değiştirip bilebilir.
Elviss Strazdins

1

Unutmayın, aynı fikir değişkenler için de geçerlidir. Yöntemler / işlevler için yaptığınız gibi değişkenlerden bahsederken statik, üye, örnek, sınıf vb. Terimlerle karşılaşacaksınız.

Görünüşe göre Obj-C topluluğunda ortak terim ivar gibi değişken, ama henüz bir Obj-C adamı değilim.


1

Yukarıdaki yanıtlara yapılan bir güncellemede, örnek yöntemlerinin bir sınıfın örneğini kullandığını kabul ederken, sınıf yöntemi yalnızca sınıf adıyla kullanılabilir.

Objective-C'de otomatik referans sayımı gerçekleştikten sonra bulut sunucusu yöntemi ile sınıf yöntemi arasında daha fazla fark yoktur.

Örneğin, [NS StringWithformat:..]bir sınıf yöntemi ve [[NSString alloc] initwihtformat:..]bir örnek yöntemi, her ikisi de ARC'den sonra aynıdır


1

Not: Bu yalnızca sahte kod biçimindedir

Sınıf yöntemi

Neredeyse tüm yapması gereken derleme zamanı . Herhangi bir kullanıcı girdisine veya hesaplamanın bir örneğe dayandırılmasına gerek yoktur. Onunla ilgili her şey sınıf / plana dayanır — bu benzersizdir, yani bir sınıf için birden fazla taslağınız yoktur. Derleme süresinde farklı varyasyonlarınız olabilir mi? Hayır, bu nedenle sınıf benzersizdir ve bu yüzden kaç kez bir sınıf yöntemi çağırsanız da ona işaret eden işaretçi aynı olacaktır.

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

Örnek Yöntemi

Aksine örnek yöntemi çalışma zamanında olur, çünkü ancak o zaman her örneklemede değişebilecek bir şeyin örneğini oluşturmuş olursunuz.

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.

Başka dillerden geliyorsanız Statik yöntemler sınıf yöntemleriyle aynıdır.
Swift'ten geliyorsanız, yazma yöntemleri sınıf yöntemleri ile aynıdır.


0

Yukarıdaki cevaplara ekleme

Sınıf yöntemi sınıfta çalışacak, bunu + stringWithFormat, sınıfın boyutu ve en önemlisi init vb.

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

Örnek Yöntemi , iki kişimiz olduğu gibi bir sınıfta olmayan bir sınıf örneği üzerinde çalışacaktır ve burada örnek yöntemini kullanmamız gereken her birinin ayrı ayrı dengesini bilmek istiyoruz. Çünkü genel yanıtı döndürmeyecek. örneğin NSSArray sayısını belirlemek gibi.

[johnson getAccountBalance];
[ankit getAccountBalance];
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.