类方法和实例方法有什么区别?
类方法和实例方法有什么区别?
实例方法是访问器(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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
就像大多数其他答案所说的那样,实例方法使用类的实例,而类方法可以仅与类名一起使用。 在 Objective-C 中,它们是这样定义的:
然后可以像这样使用它们:
一些现实世界中的类方法示例是许多 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:
They could then be used like so:
Some real world examples of class methods are the convenience methods on many Foundation classes like
NSString
's+stringWithFormat:
orNSArray
's+arrayWithArray:
. An instance method would beNSArray
's-count
method.其他答案中已经很好地涵盖了所有技术细节。 我只想分享一个简单的类比,我认为它很好地说明了类和实例之间的区别:
一个类就像一座房子的蓝图:你只有一个蓝图,并且(通常)你不能单独使用该蓝图做那么多事情。
一个实例(或对象)是您根据蓝图建造的实际房屋:您可以根据同一个蓝图建造许多房屋。 然后,您可以将每个房屋的墙壁涂成不同的颜色,就像您可以独立更改类的每个实例的属性而不影响其他实例一样。
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:
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.
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.
就像其他答案所说的那样,实例方法对一个对象进行操作并可以访问其实例变量,而类方法对整个类进行操作并且无法访问特定实例的变量(除非您将实例作为范围)。
类方法的一个很好的例子是计数器类型方法,它返回类的实例总数。 类方法以
+
开头,而实例方法以-
开头。例如:
main.m:
输出:
年龄:0
人数:2
另一个例子是,如果您希望用户能够调用一个方法,有时最好将其设为类方法。 例如,如果您有一个名为 MathFunctions 的类,则可以执行以下操作:
那么用户将调用:
而无需实例化该类!
您还可以使用类函数返回自动释放的对象,例如NSArray
接受一个对象,将其放入数组中,然后返回该数组的自动释放版本,该数组不必进行内存管理,非常适合临时数组等。
我希望您现在了解何时和/或为什么应该使用类方法!
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:
main.m:
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:
So then the user would call:
without ever having to instantiate the class!
You can also use class functions for returning autoreleased objects, like NSArray's
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!!
实例方法适用于类的实例(即对象),而类方法适用于类本身。
在 C# 中,类方法被标记为静态。 未标记为静态的方法和属性是实例方法。
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.
你的问题的答案并不特定于 Objective-C,但是在不同的语言中,类方法可能被称为静态方法。
类方法和实例方法之间的区别是
类方法
实例方法
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
Instance methods
我认为理解这一点的最好方法是查看
alloc
和init
。 正是这个解释让我理解了其中的差异。类方法
类方法应用于整个类。 如果您检查
alloc
方法,它是一个类方法,在方法声明之前用+
表示。 它是一个类方法,因为它应用于类以创建该类的特定实例。实例方法
您可以使用实例方法来修改类的特定实例,该实例对于该实例(而不是整个类)是唯一的。 例如,
init
(在方法声明之前用-
表示)是一个实例方法,因为您通常在使用创建该类后修改该类的属性>分配
。示例
您正在调用类方法
alloc
来生成该类的实例。 请注意消息的接收者是如何成为一个类的。您正在通过设置名为
myString
的NSString
实例来修改该实例的一些属性。 请注意消息的接收者是一个实例(NSString
类的对象)。I think the best way to understand this is to look at
alloc
andinit
. 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 withalloc
.Example
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.You are modifying the instance of
NSString
calledmyString
by setting some properties on that instance. Notice how the receiver of the message is an instance (object of classNSString
).类方法通常用于创建该类的实例
例如,
[NSString stringWithFormat:@"SomeParameter"];
返回一个NSString
实例以及发送给它的参数。 因此,由于它是返回其类型的对象的类方法,因此也称为便利方法。Class methods are usually used to create instances of that class
For example,
[NSString stringWithFormat:@"SomeParameter"];
returns anNSString
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.所以如果我理解正确的话。
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. Aclass
method is self contained and can operate without any dependence of the state of any object of that class. Aclass
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.实例方法对类的实例(即“对象”)进行操作。 类方法与类相关联(大多数语言对这些方法使用关键字
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).以一个产生大量汽车的游戏为例。每辆汽车都属于 CCar 类。
当汽车被实例化时,它会调用
CCar类,因此可以列出每个实例化的CCar。
假设用户完成了一个关卡,并想要删除所有汽车......您可以:
1- 浏览您手动创建的每个 CCar 的列表,然后执行
whicheverCar.remove();
或者
2- 向 CCar 添加一个removeAllCars方法,当您调用[CCarremoveAllCars]时,该方法将为您执行此操作。 即
allCars[n].remove();
或者例如,您允许用户为整个应用程序指定默认字体大小,该字体大小在启动时加载并保存。
如果没有类方法,您可能必须执行类似于
使用类方法的操作,您可以使用
[FontHandler getDefaultFontSize]
。至于removeVowels 函数,您会发现像C# 这样的语言实际上都具有某些方法,例如toLower 或toUpper。
例如
myString.removeVowels()
和String.removeVowels(myString)
(在 ObjC 中为[String removeVowels:myString]
)。在这种情况下,实例可能会调用类方法,因此两者都可用。
即
基本上,
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
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
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()
andString.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.
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.
类方法
是声明为静态的方法。 无需创建类的实例即可调用该方法。 类方法只能对类成员进行操作,而不能对实例成员进行操作,因为类方法不知道实例成员。 类的实例方法也不能从类方法内部调用,除非在该类的实例上调用它们。
实例方法
另一方面,在调用它们之前需要类的实例存在,因此需要使用 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.
在 Objective-C 中,所有方法都以“-”或“+”字符开头。
示例:
“+”和“-”字符分别指定方法是
类方法
还是实例方法
。如果我们调用这些方法,差异就会很明显。 这里的方法是在
MyClass
中声明的。实例方法
需要类的实例:在
MyClass
内部,其他方法可以使用self
调用MyClass
的实例方法:但是,必须在类本身上调用
类方法
:或者:
这不起作用:
In Objective-C all methods start with either a "-" or "+" character.
Example:
The "+" and "-" characters specify whether a method is a
class method
or aninstance 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:Inside
MyClass
other methods can call instance methods ofMyClass
usingself
:But,
class methods
must be called on the class itself:Or:
This won't work:
类方法
类方法通常创建类的新实例或检索类的某些全局属性。 类方法不对实例进行操作,也不能访问实例变量。
实例方法
实例方法对类的特定实例进行操作。 例如,您实现的访问器方法都是实例方法。 您可以使用它们来设置或获取特定对象的实例变量。
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
类方法无法更改或知道任何实例变量的值。 这应该是判断实例方法是否可以是类方法的标准。
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.
还要记住,同样的想法也适用于变量。 当谈论变量时,就像谈论方法/函数一样,你会遇到静态、成员、实例、类等术语。
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.
对上述答案的更新,我同意实例方法使用类的实例,而类方法可以仅与类名一起使用。
实例方法和实例方法之间没有任何区别。 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注意:这只是伪代码格式
类方法
几乎所有它需要做的都是在编译时。 它不需要任何用户输入,也不基于实例进行计算。 它的一切都基于类/蓝图——这是独一无二的,即一个类没有多个蓝图。 在编译时可以有不同的变化吗? 不,因此该类是唯一的,因此无论您调用一个类方法多少次,指向它的指针都是相同的。
实例方法
相反,实例方法发生在运行时期间,因为只有这样您才创建了一个在每次实例化时都可能发生变化的实例。
如果您来自其他语言,静态方法与类方法相同。
如果您来自 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.
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.
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.
添加到上面的答案
类方法将在类上工作,我们将其用于一般目的,例如+stringWithFormat,类的大小,最重要的是init等
实例方法将工作在一个类的实例上,而不是在一个类上,就像我们有两个人一样,我们想分别了解每个人的平衡,这里我们需要使用实例方法。 因为它不会返回一般响应。 例如确定 NSSArray 的计数等。
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
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.