“类方法”和“静态方法”有什么不同?

时间:2022-10-25 21:08:21

I've worked with a few different languages such as Java, C#, and Objective-C.

我使用了一些不同的语言,比如Java、c#和Objective-C。

In most languages, methods that don't require an instance of an object are called static methods. However, when it comes to Objective-C, some people get defensive when you call them static methods, and they expect you to call them class methods.

在大多数语言中,不需要对象实例的方法称为静态方法。然而,当涉及到Objective-C时,有些人会在调用静态方法时进行防御,他们希望您将其称为类方法。

Why are they called class methods instead of static methods? What is the difference between a static method and a class method?

为什么它们被称为类方法而不是静态方法?静态方法和类方法的区别是什么?

4 个解决方案

#1


69  

So my question is why are they called class methods instead of a static method? What is the difference between a static method and a class method?

我的问题是为什么它们被称为类方法而不是静态方法?静态方法和类方法的区别是什么?

From Wikipedia: Static methods neither require an instance of the class nor can they implicitly access the data (or this, self, Me, etc.) of such an instance.

从Wikipedia:静态方法既不需要类的实例,也不能隐式地访问此类实例的数据(或这个、self、Me等)。

This describes exactly what Objective-C's class methods are not.

这恰恰描述了Objective-C的类方法不是什么。

An Objective-C class method very much requires an instance that is the target of the method invocation. That is, it requires an instance of the metaclass that describes the class object being invoked.

Objective-C类方法非常需要一个实例,它是方法调用的目标。也就是说,它需要一个元类实例来描述被调用的类对象。

Unlike static methods, Objective-C's class methods can be inherited (which, in combination with having the aforementioned self, is exactly why many classes can share a single, simple, implementation of +alloc on NSObject without needing their own custom implementations) and invoking a class method goes through the exact same objc_msgSend* based dispatch mechanism as any other method call site.

与静态方法不同的是,objective - c类方法可以被继承(结合在上述的自我,就是为什么许多类可以分享一个简单的实现+ alloc NSObject无需自己的自定义实现)和调用一个类方法通过基于相同的objc_msgSend *调度机制和其他方法调用站点。

Objective-C's class methods can be overridden across the class hierarchy and they can be swizzled. None of which is supported in languages that typically offer static methods in lieu of class methods.

Objective-C的类方法可以在类层次结构中被重写,它们可以被swizzled。这些语言都不支持以静态方法代替类方法的语言。

The bottom line is that static methods and class methods are very different. While that difference is mostly transparent for day to day coding purposes, there are still situations where knowing how class methods work can save you a ton of unnecessary lines of code.

底线是静态方法和类方法是非常不同的。虽然这种差异在日常编码中几乎是透明的,但是仍然有一些情况下,知道类方法如何工作可以为您节省大量不必要的代码行。

For example, you can't do this with static methods:

例如,你不能用静态方法来做这个:

@interface AbstractClass:NSObject
+ factory;
@end

@implementation AbstractClass
+ factory
{
    return [[[self alloc] init] autorelease];
}
@end

@interface Concrete1:AbstractClass
@end
@implementation Concrete1
@end
@interface Concrete2:AbstractClass
@end
@implementation Concrete2
@end

void foo() {
    Concrete1 *c = [Concrete1 factory];
    Concrete2 *d = [Concrete2 factory];
    ... etc ...
}    

#2


4  

Though class methods and static methods are in practice the same most of the time, they are different. With static methods the class is acting as a namespace qualifier. With class methods the class itself is an object and so class methods are to the class object exactly the same thing instance methods are to an instance; as a consequence you can do the following

虽然类方法和静态方法在大多数情况下是相同的,但它们是不同的。使用静态方法,该类充当名称空间限定符。使用类方法,类本身是一个对象,类方法对于类对象来说,与实例方法完全相同;因此,您可以执行以下操作。

@interface TestClass : NSObject
+ (void)classOrInstanceMethod;
- (void)classOrInstanceMethod;
@end
...
NSArray * arr = [NSArray arrayWithObjects:
                        [[[TestClass alloc] init] autorelease],
                        [TestClass class],
                        nil];
for( id obj in arr )
    [obj classOrInstanceMethod];

which version of classOrInstanceMethod is called depends on whether obj is a class object or and instance. If you are familiar with the factory class pattern, this pattern is part of the Objective-C language.

调用classOrInstanceMethod的哪个版本取决于obj是一个类对象还是实例。如果您熟悉工厂类模式,则此模式是Objective-C语言的一部分。

#3


2  

Because it's dynamically bound, not static.

因为它是动态绑定的,而不是静态的。

Because it's really a class object's instance method.

因为它实际上是一个类对象的实例方法。

Objective-C class method is actually an object's class object's instance method.

Objective-C类方法实际上是一个对象的类对象的实例方法。

It's hard to describe with text. See nice illustration here.

很难用文字来描述。看到漂亮的插图。

http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html

http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html

#4


1  

This is purely a historical difference, mostly stemming from the fact that Objective-C was developed contemporaneously with C++, and before C++ or later languages like Java and C# had much influence. Objective-C was essentially a port of the Smalltalk object model to C, so its syntax and terminology don't necessarily seem as "C-like" as that used by C++. However, Objective-C was in no way bucking a trend by not using the term "static method", because that trend wasn't well-established back in 1983.

这纯粹是历史上的差异,主要源于Objective-C与c++的同步发展,而在c++或诸如Java和c#这样的后期语言之前,它们都有很大的影响。Objective-C本质上是一个Smalltalk对象模型到C的端口,所以它的语法和术语并不一定像c++所使用的“C-like”。然而,Objective-C并没有使用“静态方法”这一术语来抵制趋势,因为这一趋势在1983年还没有得到确认。

#1


69  

So my question is why are they called class methods instead of a static method? What is the difference between a static method and a class method?

我的问题是为什么它们被称为类方法而不是静态方法?静态方法和类方法的区别是什么?

From Wikipedia: Static methods neither require an instance of the class nor can they implicitly access the data (or this, self, Me, etc.) of such an instance.

从Wikipedia:静态方法既不需要类的实例,也不能隐式地访问此类实例的数据(或这个、self、Me等)。

This describes exactly what Objective-C's class methods are not.

这恰恰描述了Objective-C的类方法不是什么。

An Objective-C class method very much requires an instance that is the target of the method invocation. That is, it requires an instance of the metaclass that describes the class object being invoked.

Objective-C类方法非常需要一个实例,它是方法调用的目标。也就是说,它需要一个元类实例来描述被调用的类对象。

Unlike static methods, Objective-C's class methods can be inherited (which, in combination with having the aforementioned self, is exactly why many classes can share a single, simple, implementation of +alloc on NSObject without needing their own custom implementations) and invoking a class method goes through the exact same objc_msgSend* based dispatch mechanism as any other method call site.

与静态方法不同的是,objective - c类方法可以被继承(结合在上述的自我,就是为什么许多类可以分享一个简单的实现+ alloc NSObject无需自己的自定义实现)和调用一个类方法通过基于相同的objc_msgSend *调度机制和其他方法调用站点。

Objective-C's class methods can be overridden across the class hierarchy and they can be swizzled. None of which is supported in languages that typically offer static methods in lieu of class methods.

Objective-C的类方法可以在类层次结构中被重写,它们可以被swizzled。这些语言都不支持以静态方法代替类方法的语言。

The bottom line is that static methods and class methods are very different. While that difference is mostly transparent for day to day coding purposes, there are still situations where knowing how class methods work can save you a ton of unnecessary lines of code.

底线是静态方法和类方法是非常不同的。虽然这种差异在日常编码中几乎是透明的,但是仍然有一些情况下,知道类方法如何工作可以为您节省大量不必要的代码行。

For example, you can't do this with static methods:

例如,你不能用静态方法来做这个:

@interface AbstractClass:NSObject
+ factory;
@end

@implementation AbstractClass
+ factory
{
    return [[[self alloc] init] autorelease];
}
@end

@interface Concrete1:AbstractClass
@end
@implementation Concrete1
@end
@interface Concrete2:AbstractClass
@end
@implementation Concrete2
@end

void foo() {
    Concrete1 *c = [Concrete1 factory];
    Concrete2 *d = [Concrete2 factory];
    ... etc ...
}    

#2


4  

Though class methods and static methods are in practice the same most of the time, they are different. With static methods the class is acting as a namespace qualifier. With class methods the class itself is an object and so class methods are to the class object exactly the same thing instance methods are to an instance; as a consequence you can do the following

虽然类方法和静态方法在大多数情况下是相同的,但它们是不同的。使用静态方法,该类充当名称空间限定符。使用类方法,类本身是一个对象,类方法对于类对象来说,与实例方法完全相同;因此,您可以执行以下操作。

@interface TestClass : NSObject
+ (void)classOrInstanceMethod;
- (void)classOrInstanceMethod;
@end
...
NSArray * arr = [NSArray arrayWithObjects:
                        [[[TestClass alloc] init] autorelease],
                        [TestClass class],
                        nil];
for( id obj in arr )
    [obj classOrInstanceMethod];

which version of classOrInstanceMethod is called depends on whether obj is a class object or and instance. If you are familiar with the factory class pattern, this pattern is part of the Objective-C language.

调用classOrInstanceMethod的哪个版本取决于obj是一个类对象还是实例。如果您熟悉工厂类模式,则此模式是Objective-C语言的一部分。

#3


2  

Because it's dynamically bound, not static.

因为它是动态绑定的,而不是静态的。

Because it's really a class object's instance method.

因为它实际上是一个类对象的实例方法。

Objective-C class method is actually an object's class object's instance method.

Objective-C类方法实际上是一个对象的类对象的实例方法。

It's hard to describe with text. See nice illustration here.

很难用文字来描述。看到漂亮的插图。

http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html

http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html

#4


1  

This is purely a historical difference, mostly stemming from the fact that Objective-C was developed contemporaneously with C++, and before C++ or later languages like Java and C# had much influence. Objective-C was essentially a port of the Smalltalk object model to C, so its syntax and terminology don't necessarily seem as "C-like" as that used by C++. However, Objective-C was in no way bucking a trend by not using the term "static method", because that trend wasn't well-established back in 1983.

这纯粹是历史上的差异,主要源于Objective-C与c++的同步发展,而在c++或诸如Java和c#这样的后期语言之前,它们都有很大的影响。Objective-C本质上是一个Smalltalk对象模型到C的端口,所以它的语法和术语并不一定像c++所使用的“C-like”。然而,Objective-C并没有使用“静态方法”这一术语来抵制趋势,因为这一趋势在1983年还没有得到确认。