类和实例方法有什么区别?

Dev*_*ted 442 oop methods objective-c class-method instance-methods

类方法和实例方法有什么区别?

实例方法是访问器(getter和setter),而类方法几乎是其他所有方法吗?

Cor*_*ger 667

像大多数其他答案所说的那样,实例方法使用类的实例,而类方法只能使用类名.在Objective-C中,它们是如此定义的:

@interface MyClass : NSObject

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

@end
Run Code Online (Sandbox Code Playgroud)

然后可以这样使用它们:

[MyClass aClassMethod];

MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];
Run Code Online (Sandbox Code Playgroud)

类方法的一些真实世界的例子是许多基础类的便利方法,如NSString's +stringWithFormat:NSArray's +arrayWithArray:.实例的方法是NSArray-count方法.

  • 我想补充一点,在许多其他语言中,类方法被称为"静态"方法.回答原始问题,访问器是实例方法,因为它们设置并获取特定实例的状态.在上面的示例中,NSArray计数返回特定实例中的对象数. (147认同)
  • 好答案.值得注意的是,您将看到描述方法的特定简写符号.例如,+ [NSString stringWithFormat:]是NSString上的类方法+ stringWithFormat :; - [NSArray objectAtIndex:]是一个实例方法.具有多个选择器部分的方法类似于 - [NSMutableDictionary setObject:forKey:]等.您经常会在Cocoa响应,文档和Xcode中看到这种表示法. (7认同)
  • "而类方法只能与类名一起使用." 或者类对象 (2认同)
  • 对不起我的兴奋...但我刚刚了解了它的差异和潜力.类方法摇滚,单身类也是如此!我已经爱上了!<3 (2认同)
  • @BrianPan静态和类方法不一样.它们是相似的,但它们的不同命名的原因是它们的工作方式不同.例如,无法覆盖静态方法. (2认同)

Joh*_*rug 191

所有技术细节都在其他答案中得到了很好的介绍.我只是想分享一个简单的类比,我认为很好地说明了类和实例之间的区别:

在此输入图像描述

一个就像一个房子的蓝图:你只有一个蓝图,而且(通常)你不能单独用蓝图做那么多.

在此输入图像描述

一个实例(或对象)是实际的房子,你构建基于蓝图:您可以从同一个蓝图建造大量房屋.然后,您可以在每个房屋中为墙壁绘制不同的颜色,就像您可以独立更改类的每个实例的属性而不影响其他实例一样.

  • @JohannesFahrenkrug在这里很好地解释了类和对象的概念.实际的问题不是"类方法和实例方法之间的区别"; (6认同)

mic*_*moo 102

与其他答案一样,实例方法对一个对象进行操作并可以访问其实例变量,而一个类方法作为一个整体对一个类进行操作,并且无法访问特定实例的变量(除非您将该实例作为一个参数).

类方法的一个很好的例子是计数器类型方法,它返回类的实例总数.类方法以a开头+,而实例以a 开头-.例如:

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
Run Code Online (Sandbox Code Playgroud)

main.m文件:

MNPerson *micmoo = [[MNPerson alloc] init];
MNPerson *jon = [[MNPerson alloc] init];
NSLog(@"Age: %d",[micmoo age]);
NSLog(@"%Number Of people: %d",[MNPerson population]);
Run Code Online (Sandbox Code Playgroud)

输出:年龄:0人数:2

另一个例子是,如果你有一个你希望用户能够调用的方法,有时可以将它作为一个类方法.例如,如果您有一个名为MathFunctions的类,则可以执行以下操作:

+ (int)square:(int)num{ 
      return num * num;
}
Run Code Online (Sandbox Code Playgroud)

那么用户会打电话给:

[MathFunctions square:34];
Run Code Online (Sandbox Code Playgroud)

无需实例化课程!

您还可以使用类函数来返回自动释放的对象,例如NSArray

+ (NSArray *)arrayWithObject:(id)object
Run Code Online (Sandbox Code Playgroud)

这需要一个对象,将它放在一个数组中,并返回一个不需要内存管理的自动释放版本的数组,非常适合temperorary数组,什么不是.

我希望你现在明白何时和/或为什么你应该使用类方法!!

  • 请原谅我的新手困惑,但为什么你需要实例变量"age"和实例方法"age"?不会使用@synthetize创建实例变量"age"的getter和setter吗? (2认同)

Rob*_*ick 36

实例方法适用于类的实例(即对象),而类方法适用于类本身.

在C#中,类方法标记为静态.未标记为static的方法和属性是实例方法.

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}
Run Code Online (Sandbox Code Playgroud)

  • 没有伤害.答案的第一部分作为一般的OOP原则是正确的,它绝对适用于Objective-C.如果你不想看到这样的问题,你可以在你的标签列表中添加"objective-c"以忽略,尽管任何参与都是值得欢迎的.:-) (6认同)

Ada*_*ite 16

我认为理解这一点的最好方法是看看allocinit.正是这种解释让我理解了这些差异.

类方法

类方法作为一个整体应用于类.如果检查alloc方法,那就是+方法声明之前表示的类方法.它是一个类方法,因为它应用于类来创建该类的特定实例.

实例方法

您使用实例方法来修改该实例唯一的特定类实例,而不是整个类.init例如(-在方法声明之前用a表示),是一个实例方法,因为您通常在创建该类后修改该类的属性alloc.

NSString *myString = [NSString alloc];
Run Code Online (Sandbox Code Playgroud)

您正在调用类方法alloc以生成该类的实例.注意消息的接收者是一个类.

[myString initWithFormat:@"Hope this answer helps someone"];
Run Code Online (Sandbox Code Playgroud)

您正在通过在该实例上设置一些属性来修改被NSString调用myString的实例.注意消息的接收者是一个实例(类的对象NSString).


hha*_*fez 15

您的问题的答案并非特定于objective-c,但是在不同的语言中,Class方法可能被称为静态方法.

类方法和实例方法之间的区别是

类方法

  • 对类变量进行操作(它们无法访问实例变量)
  • 不要求实例化对象
  • 有时可能是代码气味(一些不熟悉OOP的人用作在OO环境中进行结构化编程的拐杖)

实例方法

  • 对实例变量和类变量进行操作
  • 必须有一个instanciated对象来操作


ios*_*kie 6

类方法通常用于创建该类的实例

例如,[NSString stringWithFormat:@"SomeParameter"];返回一个NSString带有发送给它的参数的实例.因此,因为它是返回其类型对象的Class方法,所以它也称为便捷方法.


Sid*_*rth 6

所以如果我理解正确的话.

一个class方法不需要你来分配对象的实例使用/处理它.甲class方法是自包含的并且可以在不那类的任何对象的状态中的任意依赖性操作.class期望一种方法为其自己的所有工作分配内存并在完成时解除分配,因为该类的任何实例都不能释放先前对类方法的调用中分配的任何内存.

一种instance方法恰恰相反.除非您分配该类的实例,否则无法调用它.它就像一个普通的类,它有一个构造函数,可以有一个析构函数(清理所有分配的内存).

最有可能(除非您正在编写可重用的库,否则您不需要class变量.