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

发布于 2024-07-25 19:41:10 字数 71 浏览 10 评论 0原文

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

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

What's the difference between a class method and an instance method?

Are instance methods the accessors (getters and setters) while class methods are pretty much everything else?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

心奴独伤 2024-08-01 19:41:10

就像大多数其他答案所说的那样,实例方法使用类的实例,而类方法可以仅与类名一起使用。 在 Objective-C 中,它们是这样定义的:

@interface MyClass : NSObject

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

@end

然后可以像这样使用它们:

[MyClass aClassMethod];

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

一些现实世界中的类方法示例是许多 Foundation 类上的便捷方法,例如 NSString+stringWithFormat:< /code> 或 NSArray+arrayWithArray:。 实例方法是 NSArray 的 -count 方法。

Like most of the other answers have said, instance methods use an instance of a class, whereas a class method can be used with just the class name. In Objective-C they are defined thusly:

@interface MyClass : NSObject

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

@end

They could then be used like so:

[MyClass aClassMethod];

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

Some real world examples of class methods are the convenience methods on many Foundation classes like NSString's +stringWithFormat: or NSArray's +arrayWithArray:. An instance method would be NSArray's -count method.

桃扇骨 2024-08-01 19:41:10

其他答案中已经很好地涵盖了所有技术细节。 我只想分享一个简单的类比,我认为它很好地说明了类和实例之间的区别:

在此处输入图像描述

一个就像一座房子的蓝图:你只有一个蓝图,并且(通常)你不能单独使用该蓝图做那么多事情。

在此处输入图像描述

一个实例(或对象)是您根据蓝图建造的实际房屋:您可以根据同一个蓝图建造许多房屋。 然后,您可以将每个房屋的墙壁涂成不同的颜色,就像您可以独立更改类的每个实例的属性而不影响其他实例一样。

All the technical details have been nicely covered in the other answers. I just want to share a simple analogy that I think nicely illustrates the difference between a class and an instance:

enter image description here

A class is like the blueprint of a house: You only have one blueprint and (usually) you can't do that much with the blueprint alone.

enter image description here

An instance (or an object) is the actual house that you build based on the blueprint: You can build lots of houses from the same blueprint. You can then paint the walls a different color in each of the houses, just as you can independently change the properties of each instance of a class without affecting the other instances.

旧城烟雨 2024-08-01 19:41:10

就像其他答案所说的那样,实例方法对一个对象进行操作并可以访问其实例变量,而类方法对整个类进行操作并且无法访问特定实例的变量(除非您将实例作为范围)。

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

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

接受一个对象,将其放入数组中,然后返回该数组的自动释放版本,该数组不必进行内存管理,非常适合临时数组等。

我希望您现在了解何时和/或为什么应该使用类方法!

Like the other answers have said, instance methods operate on an object and has access to its instance variables, while a class method operates on a class as a whole and has no access to a particular instance's variables (unless you pass the instance in as a parameter).

A good example of an class method is a counter-type method, which returns the total number of instances of a class. Class methods start with a +, while instance ones start with an -.
For example:

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

Output:
Age: 0
Number Of people: 2

Another example is if you have a method that you want the user to be able to call, sometimes its good to make that a class method. For example, if you have a class called MathFunctions, you can do this:

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

So then the user would call:

[MathFunctions square:34];

without ever having to instantiate the class!

You can also use class functions for returning autoreleased objects, like NSArray's

+ (NSArray *)arrayWithObject:(id)object

That takes an object, puts it in an array, and returns an autoreleased version of the array that doesn't have to be memory managed, great for temperorary arrays and what not.

I hope you now understand when and/or why you should use class methods!!

酷到爆炸 2024-08-01 19:41:10

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

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

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

An instance method applies to an instance of the class (i.e. an object) whereas a class method applies to the class itself.

In C# a class method is marked static. Methods and properties not marked static are instance methods.

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}
趁年轻赶紧闹 2024-08-01 19:41:10

你的问题的答案并不特定于 Objective-C,但是在不同的语言中,类方法可能被称为静态方法。

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

类方法

  • 对类变量进行操作(它们不能访问实例变量)
  • 不需要实例化对象才能应用
  • 有时可能会产生代码味道(一些刚接触 OOP 的人使用 as在 OO 环境中进行结构化编程的拐杖)

实例方法

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

The answer to your question is not specific to objective-c, however in different languages, Class methods may be called static methods.

The difference between class methods and instance methods are

Class methods

  • Operate on Class variables (they can not access instance variables)
  • Do not require an object to be instantiated to be applied
  • Sometimes can be a code smell (some people who are new to OOP use as a crutch to do Structured Programming in an OO enviroment)

Instance methods

  • Operate on instances variables and class variables
  • Must have an instanciated object to operate on
风月客 2024-08-01 19:41:10

我认为理解这一点的最好方法是查看 allocinit。 正是这个解释让我理解了其中的差异。

类方法

类方法应用于整个类。 如果您检查 alloc 方法,它是一个类方法,在方法声明之前用 + 表示。 它是一个类方法,因为它应用于类以创建该类的特定实例。

实例方法

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

示例

NSString *myString = [NSString alloc];

您正在调用类方法alloc 来生成该类的实例。 请注意消息的接收者是如何成为一个类的。

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

您正在通过设置名为 myStringNSString 实例来修改该实例的一些属性。 请注意消息的接收者是一个实例(NSString 类的对象)。

I think the best way to understand this is to look at alloc and init. It was this explanation that allowed me to understand the differences.

Class Method

A class method is applied to the class as a whole. If you check the alloc method, that's a class method denoted by the + before the method declaration. It's a class method because it is applied to the class to make a specific instance of that class.

Instance Method

You use an instance method to modify a specific instance of a class that is unique to that instance, rather than to the class as a whole. init for example (denoted with a - before the method declaration), is an instance method because you are normally modifying the properties of that class after it has been created with alloc.

Example

NSString *myString = [NSString alloc];

You are calling the class method alloc in order to generate an instance of that class. Notice how the receiver of the message is a class.

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

You are modifying the instance of NSString called myString by setting some properties on that instance. Notice how the receiver of the message is an instance (object of class NSString).

北笙凉宸 2024-08-01 19:41:10

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

例如,[NSString stringWithFormat:@"SomeParameter"]; 返回一个 NSString 实例以及发送给它的参数。 因此,由于它是返回其类型的对象的类方法,因此也称为便利方法。

Class methods are usually used to create instances of that class

For example, [NSString stringWithFormat:@"SomeParameter"]; returns an NSString instance with the parameter that is sent to it. Hence, because it is a Class method that returns an object of its type, it is also called a convenience method.

恋你朝朝暮暮 2024-08-01 19:41:10

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

class 方法不需要您分配该对象的实例来使用/处理它。 class 方法是自包含的,并且可以在不依赖于该类的任何对象的状态的情况下进行操作。 class 方法应该为其自己的所有工作分配内存,并在完成后释放内存,因为该类的任何实例都无法释放先前调用该类方法时分配的任何内存。

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

大多数情况下(除非您正在编写可重用的库,否则您不应该需要 class 变量。

So if I understand it correctly.

A class method does not need you to allocate instance of that object to use / process it. A class method is self contained and can operate without any dependence of the state of any object of that class. A class method is expected to allocate memory for all its own work and deallocate when done, since no instance of that class will be able to free any memory allocated in previous calls to the class method.

A instance method is just the opposite. You cannot call it unless you allocate a instance of that class. Its like a normal class that has a constructor and can have a destructor (that cleans up all the allocated memory).

In most probability (unless you are writing a reusable library, you should not need a class variable.

心凉 2024-08-01 19:41:10

实例方法对类的实例(即“对象”)进行操作。 类方法与类相关联(大多数语言对这些方法使用关键字static)。

Instances methods operate on instances of classes (ie, "objects"). Class methods are associated with classes (most languages use the keyword static for these guys).

他不在意 2024-08-01 19:41:10

以一个产生大量汽车的游戏为例。每辆汽车都属于 CCar 类。
当汽车被实例化时,它会调用

[CCar registerCar:self]

CCar类,因此可以列出每个实例化的CCar。
假设用户完成了一个关卡,并想要删除所有汽车......您可以:
1- 浏览您手动创建的每个 CCar 的列表,然后执行 whicheverCar.remove();
或者
2- 向 CCar 添加一个removeAllCars方法,当您调用[CCarremoveAllCars]时,该方法将为您执行此操作。 即 allCars[n].remove();

或者例如,您允许用户为整个应用程序指定默认字体大小,该字体大小在启动时加载并保存。
如果没有类方法,您可能必须执行类似于

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

使用类方法的操作,您可以使用[FontHandler getDefaultFontSize]

至于removeVowels 函数,您会发现像C# 这样的语言实际上都具有某些方法,例如toLower 或toUpper。

例如 myString.removeVowels()String.removeVowels(myString) (在 ObjC 中为 [String removeVowels:myString])。

在这种情况下,实例可能会调用类方法,因此两者都可用。

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]

没有明确的答案,但如果您觉得添加一个类方法会改进您的代码,请给出试一试,请记住,类方法只会让您使用其他类方法/变量。

Take for example a game where lots of cars are spawned.. each belongs to the class CCar.
When a car is instantiated, it makes a call to

[CCar registerCar:self]

So the CCar class, can make a list of every CCar instantiated.
Let's say the user finishes a level, and wants to remove all cars... you could either:
1- Go through a list of every CCar you created manually, and do whicheverCar.remove();
or
2- Add a removeAllCars method to CCar, which will do that for you when you call [CCar removeAllCars]. I.e. allCars[n].remove();

Or for example, you allow the user to specify a default font size for the whole app, which is loaded and saved at startup.
Without the class method, you might have to do something like

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

With the class method, you could get away with [FontHandler getDefaultFontSize].

As for your removeVowels function, you'll find that languages like C# actually have both with certain methods such as toLower or toUpper.

e.g. myString.removeVowels() and String.removeVowels(myString) (in ObjC that would be [String removeVowels:myString]).

In this case the instance likely calls the class method, so both are available.
i.e.

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

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

basically, myString.toLower() calls [String toLower:ownValue]

There's no definitive answer, but if you feel like shoving a class method in would improve your code, give it a shot, and bear in mind that a class method will only let you use other class methods/variables.

病女 2024-08-01 19:41:10

类方法

是声明为静态的方法。 无需创建类的实例即可调用该方法。 类方法只能对类成员进行操作,而不能对实例成员进行操作,因为类方法不知道实例成员。 类的实例方法也不能从类方法内部调用,除非在该类的实例上调用它们。

实例方法

另一方面,在调用它们之前需要类的实例存在,因此需要使用 new 关键字创建类的实例。 实例方法对类的特定实例进行操作。 实例方法未声明为静态。

class methods

are methods which are declared as static. The method can be called without creating an instance of the class. Class methods can only operate on class members and not on instance members as class methods are unaware of instance members. Instance methods of the class can also not be called from within a class method unless they are being called on an instance of that class.

Instance methods

on the other hand require an instance of the class to exist before they can be called, so an instance of a class needs to be created by using the new keyword. Instance methods operate on specific instances of classes. Instance methods are not declared as static.

倾城泪 2024-08-01 19:41:10

在 Objective-C 中,所有方法都以“-”或“+”字符开头。
示例:

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

+ (void) classMethod;
@end

“+”和“-”字符分别指定方法是类方法还是实例方法

如果我们调用这些方法,差异就会很明显。 这里的方法是在 MyClass 中声明的。

实例方法需要类的实例:

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

MyClass内部,其他方法可以使用self调用MyClass的实例方法:

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

但是,必须在类本身上调用类方法

[MyClass classMethod];

或者:

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

这不起作用:

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

In Objective-C all methods start with either a "-" or "+" character.
Example:

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

+ (void) classMethod;
@end

The "+" and "-" characters specify whether a method is a class method or an instance method respectively.

The difference would be clear if we call these methods. Here the methods are declared in MyClass.

instance method require an instance of the class:

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

Inside MyClass other methods can call instance methods of MyClass using self:

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

But, class methods must be called on the class itself:

[MyClass classMethod];

Or:

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

This won't work:

// Error
[myClass classMethod];
// Error
[self classMethod];
云归处 2024-08-01 19:41:10

类方法


类方法通常创建类的新实例或检索类的某些全局属性。 类方法不对实例进行操作,也不能访问实例变量。


实例方法


实例方法对类的特定实例进行操作。 例如,您实现的访问器方法都是实例方法。 您可以使用它们来设置或获取特定对象的实例变量。


INVOKE


要调用实例方法,请将消息发送到类的实例。

要调用类方法,您可以直接将消息发送到该类。


来源: IOS - Objective-C - 类方法和实例方法

CLASS METHODS


A class method typically either creates a new instance of the class or retrieves some global properties of the class. Class methods do not operate on an instance or have any access to instance variable.


INSTANCE METHODS


An instance method operates on a particular instance of the class. For example, the accessors method that you implemented are all instance methods. You use them to set or get the instance variables of a particular object.


INVOKE


To invoke an instance method, you send the message to an instance of the class.

To invoke a class method, you send the message to the class directly.


Source: IOS - Objective-C - Class Methods And Instance Methods

智商已欠费 2024-08-01 19:41:10

类方法无法更改或知道任何实例变量的值。 这应该是判断实例方法是否可以是类方法的标准。

Class methods can't change or know the value of any instance variable. That should be the criteria for knowing if an instance method can be a class method.

回忆凄美了谁 2024-08-01 19:41:10

还要记住,同样的想法也适用于变量。 当谈论变量时,就像谈论方法/函数一样,你会遇到静态、成员、实例、类等术语。

Obj-C 社区中的通用术语似乎是实例变量 ivar,但我还不是 Obj-C 人。

Also remember, the same idea applies to variables. You will come across terms like static, member, instance, class and so on when talking about variables the same as you would for methods/functions.

It seems the common term in the Obj-C community is ivar for instance variable, but I am not an Obj-C guy, yet.

和影子一齐双人舞 2024-08-01 19:41:10

对上述答案的更新,我同意实例方法使用类的实例,而类方法可以仅与类名一起使用。

实例方法和实例方法之间没有任何区别。 Objective-C 中出现了自动引用计数之后的类方法。

例如[NS StringWithformat:..] 一个类方法& [[NSString alloc] initwihtformat:..] 实例方法,ARC后两者相同

An update to the above answers, I agree instance methods use an instance of a class, whereas a class method can be used with just the class name.

There is NO more any difference between instance method & class method after automatic reference counting came to existence in Objective-C.

For Example[NS StringWithformat:..] a class method & [[NSString alloc] initwihtformat:..] an instance method, both are same after ARC

单身情人 2024-08-01 19:41:10

注意:这只是伪代码格式

类方法

几乎所有它需要做的都是在编译时。 它不需要任何用户输入,也不基于实例进行计算。 它的一切都基于类/蓝图——这是独一无二的,即一个类没有多个蓝图。 在编译时可以有不同的变化吗? 不,因此该类是唯一的,因此无论您调用一个类方法多少次,指向它的指针都是相同的。

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

实例方法

相反,实例方法发生在运行时期间,因为只有这样您才创建了一个在每次实例化时都可能发生变化的实例。

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.

如果您来自其他语言,静态方法与类方法相同。
如果您来自 Swift,类型方法与类方法相同。

Note: This is only in pseudo code format

Class method

Almost does all it needs to do is during compile time. It doesn't need any user input, nor the computation of it is based on an instance. Everything about it is based on the class/blueprint——which is unique ie you don't have multiple blueprints for one class. Can you have different variations during compile time? No, therefore the class is unique and so no matter how many times you call a class method the pointer pointing to it would be the same.

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

Instance Method

On the contrary instance method happens during runtime, since it is only then that you have created an instance of something which could vary upon every instantiation.

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.

If you are coming from other languages Static methods are same as class methods.
If you are coming from Swift, type methods are same as class methods.

向地狱狂奔 2024-08-01 19:41:10

添加到上面的答案

类方法将在类上工作,我们将其用于一般目的,例如+stringWithFormat,类的大小,最重要的是init等

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

实例方法将工作在一个类的实例上,而不是在一个类上,就像我们有两个人一样,我们想分别了解每个人的平衡,这里我们需要使用实例方法。 因为它不会返回一般响应。 例如确定 NSSArray 的计数等。

[johnson getAccountBalance];
[ankit getAccountBalance];

Adding to above answers

Class method will work on class, we will use this for general purpose where like +stringWithFormat, size of class and most importantly for init etc

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

Instance Method will work on an instance of a class not on a class like we are having two persons and we want to get know the balance of each separately here we need to use instance method. Because it won't return general response. e.g. like determine the count of NSSArray etc.

[johnson getAccountBalance];
[ankit getAccountBalance];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文