В чем разница между методами класса и экземпляра? - PullRequest
437 голосов
/ 28 июня 2009

В чем разница между методом класса и методом экземпляра?

Являются ли методы экземпляра средствами доступа (получателями и установщиками), в то время как методы класса являются почти всем остальным?

Ответы [ 18 ]

663 голосов
/ 28 июня 2009

Как говорилось в большинстве других ответов, методы экземпляра используют экземпляр класса, тогда как метод класса может использоваться только с именем класса. В Objective-C они определены так:

@interface MyClass : NSObject

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

@end

Затем их можно использовать так:

[MyClass aClassMethod];

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

Некоторыми реальными примерами методов класса являются удобные методы для многих базовых классов, таких как NSString +stringWithFormat: или NSArray * +arrayWithArray: Метод экземпляра будет NSArray -count метод.

191 голосов
/ 08 мая 2013

Все технические детали были хорошо описаны в других ответах. Я просто хочу поделиться простой аналогией, которая, на мой взгляд, прекрасно иллюстрирует разницу между классом и экземпляром:

enter image description here

A класс подобен проекту дома: у вас есть только один проект и (как правило) вы не можете сделать так много только с одним проектом.

enter image description here

Экземпляр (или объект ) - это фактический дом , который вы строите на основе чертежа: вы можете построить множество домов из одного чертежа , Затем вы можете покрасить стены в разные цвета в каждом из домов, так же как вы можете независимо изменять свойства каждого экземпляра класса, не затрагивая другие экземпляры.

102 голосов
/ 28 июня 2009

Как и в других ответах, методы экземпляра работают с объектом и имеют доступ к его переменным экземпляра, а метод класса работает с классом в целом и не имеет доступа к переменным конкретного экземпляра (если вы не передаете экземпляр в качестве параметра).

Хорошим примером метода класса является метод счетного типа, который возвращает общее количество экземпляров класса. Методы класса начинаются с +, а методы экземпляра начинаются с -. Например:

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

Выход: Возраст: 0 Количество человек: 2

Другой пример: если у вас есть метод, который вы хотите, чтобы пользователь мог вызывать, иногда полезно сделать его методом класса. Например, если у вас есть класс с именем MathFunctions, вы можете сделать это:

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

Тогда пользователь будет звонить:

[MathFunctions square:34];

без необходимости создания экземпляра класса!

Вы также можете использовать функции класса для возврата автоматически выпущенных объектов, например NSArray

+ (NSArray *)arrayWithObject:(id)object

Это берет объект, помещает его в массив и возвращает автоматически выпущенную версию массива, которая не должна управляться памятью, отлично подходит для временных массивов, а что нет.

Надеюсь, теперь вы понимаете, когда и / или почему вы должны использовать методы класса !!

36 голосов
/ 28 июня 2009

Метод экземпляра применяется к экземпляру класса (то есть объекту), тогда как метод класса применяется к самому классу.

В C # метод класса помечен как статический. Методы и свойства, не помеченные как статические, являются методами экземпляра.

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}
16 голосов
/ 07 ноября 2012

Я думаю, что лучший способ понять это - взглянуть на alloc и init. Именно это объяснение позволило мне понять различия.

Метод класса

Метод класса применяется к классу в целом. Если вы проверите метод alloc, это метод класса, обозначенный + перед объявлением метода. Это метод класса, потому что он применяется к классу для создания конкретного экземпляра этого класса.

Метод экземпляра

Вы используете метод экземпляра для изменения конкретного экземпляра класса, который является уникальным для этого экземпляра, а не для класса в целом. Например, init (обозначается - перед объявлением метода), является методом экземпляра, поскольку обычно вы изменяете свойства этого класса после того, как он был создан с помощью alloc.

* ** 1 022 тысяча двадцать-один * Пример
NSString *myString = [NSString alloc];

Вы вызываете метод класса alloc для генерации экземпляра этого класса. Обратите внимание, что получатель сообщения является классом.

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

Вы изменяете экземпляр NSString с именем myString, устанавливая некоторые свойства для этого экземпляра. Обратите внимание, что получатель сообщения является экземпляром (объект класса NSString).

15 голосов
/ 28 июня 2009

Ответ на ваш вопрос не является специфичным для target-c, однако в разных языках методы класса могут называться статическими методами.

Разница между методами класса и методами экземпляра составляет

Методы класса

  • Работа с переменными класса (они не могут получить доступ к переменным экземпляра)
  • Не требуется, чтобы объект создавался для применения
  • Иногда может быть запах кода (некоторые люди, которые плохо знакомы с ООП, используют в качестве опоры для выполнения структурированного программирования в среде ОО)

Методы экземпляра

  • Работа с переменными экземпляров и переменными класса
  • Должен иметь инстанцированный объект для работы
6 голосов
/ 24 мая 2013

Так что, если я правильно понимаю.

Метод class не требует, чтобы вы выделяли экземпляр этого объекта для его использования / обработки. Метод class является самодостаточным и может работать независимо от состояния любого объекта этого класса. Ожидается, что метод class выделит память для всей своей работы и освободит ее после завершения, поскольку ни один экземпляр этого класса не сможет освободить память, выделенную в предыдущих вызовах метода класса.

A instance метод как раз наоборот. Вы не можете вызвать его, если не выделите экземпляр этого класса. Это как обычный класс, который имеет конструктор и может иметь деструктор (который очищает всю выделенную память).

В большинстве случаев (если вы не пишете библиотеку многократного использования, вам не нужна переменная class.

6 голосов
/ 09 ноября 2010

Методы класса обычно используются для создания экземпляров этого класса

Например, [NSString stringWithFormat:@"SomeParameter"]; возвращает экземпляр NSString с параметром, который ему отправляется. Следовательно, поскольку это метод класса, который возвращает объект своего типа, его также называют вспомогательным методом.

4 голосов
/ 28 июня 2009

Методы экземпляров работают с экземплярами классов (т. Е. «Объектами»). Методы класса связаны с классами (большинство языков используют ключевое слово static для этих парней).

3 голосов
/ 16 ноября 2011

Возьмем, к примеру, игру, в которой появляется множество автомобилей .. каждый из них принадлежит к классу CCar. Когда создается автомобиль, он звонит на

[CCar registerCar:self]

Таким образом, класс CCar может составить список каждого экземпляра CCar. Допустим, пользователь заканчивает уровень и хочет удалить все машины ... вы можете либо: 1- Просмотрите список всех CCar, которые вы создали вручную, и выполните whicheverCar.remove(); или же 2- Добавьте метод removeAllCars в CCar, который сделает это за вас при вызове [CCar removeAllCars]. То есть allCars[n].remove();

Или, например, вы позволяете пользователю указать размер шрифта по умолчанию для всего приложения, которое загружается и сохраняется при запуске. Без метода класса вам, возможно, придется сделать что-то вроде

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

С помощью метода класса вы можете обойтись без [FontHandler getDefaultFontSize].

Что касается функции removeVowels, вы обнаружите, что языки, подобные C #, на самом деле имеют оба метода, таких как toLower или toUpper.

например. myString.removeVowels() и String.removeVowels(myString) (в ObjC это будет [String removeVowels:myString]).

В этом случае экземпляр, скорее всего, вызывает метод класса, поэтому доступны оба. т.е. * +1021 *

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

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

в основном myString.toLower() звонки [String toLower:ownValue]

Нет однозначного ответа, но если вы чувствуете, что использование метода класса улучшит ваш код, попробуйте его и учтите, что метод класса позволит вам использовать только другие методы / переменные класса.

...