类和实例方法有什么区别?
类方法和实例方法有什么区别?
实例方法访问器(getter和setter),而类方法几乎是一切?
和大多数其他答案一样,实例方法使用一个类的实例,而类方法只能与类名一起使用。 在Objective-C中,它们是这样定义的:
@interface MyClass : NSObject + (void)aClassMethod; - (void)anInstanceMethod; @end
他们可以这样使用:
[MyClass aClassMethod]; MyClass *object = [[MyClass alloc] init]; [object anInstanceMethod];
类方法的一些真实世界的例子是许多基类的便利方法,如NSString
的+stringWithFormat:
或NSArray
的+arrayWithArray:
+stringWithFormat:
实例方法是NSArray
的-count
方法。
所有的技术细节已经在其他答案中得到了很好的阐述。 我只想分享一个简单的比喻,我可以很好地说明一个类和一个实例之间的区别:
一个class级就像一个房子的蓝图 :你只有一个蓝图,而且(通常情况下)你不能单凭这个蓝图来做那么多事情。
实例 (或对象 )是您根据蓝图构build的实际房屋 :您可以从同一份蓝图构build大量房屋。 然后,您可以在每个房屋中为墙壁涂上不同的颜色,就像您可以独立更改每个实例类的属性而不影响其他实例一样。
和其他答案一样,实例方法对一个对象进行操作,并且可以访问其实例variables,而类方法作为一个整体对类进行操作,并且不能访问特定实例的variables(除非将实例作为参数)。
类方法的一个很好的例子是一个反types方法,它返回一个类的实例总数。 类方法以+
开始,而实例以。开头。 例如:
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
这需要一个对象,把它放在一个数组中,并返回一个不需要内存pipe理的数组的自动释放版本,非常适用于Temrorary数组,而不是。
我希望你现在明白什么时候和/或为什么你应该使用类方法!
实例方法适用于类的实例(即对象),而类方法适用于类本身。
在C#中,类方法标记为静态。 未标记为静态的方法和属性是实例方法。
class Foo { public static void ClassMethod() { ... } public void InstanceMethod() { ... } }
你的问题的答案不是特定于objective-c,但是在不同的语言中,Class方法可能被称为静态方法。
类方法和实例方法的区别在于
类方法
- 在类variables上操作(它们不能访问实例variables)
- 不要求要实例化一个对象来应用
- 有时候可能是一种代码异味(有些人是OOP中使用OOP作为新手来进行结构化编程的新手)
实例方法
- 操作实例variables和类variables
- 必须有一个instanciated对象来操作
我认为理解这个最好的方法是看alloc
和init
。 这是这个解释,让我了解的差异。
类方法
一个类的方法被应用到整个类中。 如果你检查alloc
方法,这是方法声明之前用+
表示的类方法。 这是一个类方法,因为它被应用于类来创build该类的特定实例。
实例方法
您使用实例方法来修改对该实例唯一的类的特定实例,而不是整个类。 例如init
(在方法声明之前用-
表示)是一个实例方法,因为通常在使用alloc
创build该类之后,通常会修改该类的属性。
例
NSString *myString = [NSString alloc];
您正在调用类方法alloc
以生成该类的一个实例。 注意消息的接收者是一个类。
[myString initWithFormat:@"Hope this answer helps someone"];
您正在通过在该实例上设置一些属性来修改名为myString
的NSString
实例。 注意消息的接收者是一个实例( NSString
类的对象)。
所以如果我理解正确的话。
class
方法不需要你分配该对象的实例来使用/处理它。 class
方法是自包含的,并且可以在不依赖于该类的任何对象的状态的情况下运行。 一个class
方法需要为所有自己的工作分配内存,并在完成时释放内存,因为该类的任何实例都不能释放先前对类方法调用中分配的内存。
instance
方法正好相反。 除非您分配该类的实例,否则不能调用它。 它就像一个普通的类,它有一个构造函数,可以有一个析构函数(清理所有分配的内存)。
大多数情况下(除非你正在编写一个可重用的库,你不应该需要一个class
variables。
类方法通常用于创build该类的实例
例如, [NSString stringWithFormat:@"SomeParameter"];
使用发送给它的参数返回一个NSString
实例。 因此,因为它是一个返回types对象的类方法,所以它也被称为方便方法。
实例方法对类的实例(即“对象”)进行操作。 类方法与类关联(大多数语言对这些人使用关键字static
)。
举个例子,一个游戏里面有很多汽车,每个都属于CCar类。 当一辆汽车被实例化时,它打电话给
[CCar registerCar:self]
所以CCar类可以使每个CCar实例化的列表。 比方说,用户完成一个级别,并想要删除所有的汽车…你可以:1-通过手动创build的每个CCar的列表,并做whicheverCar.remove();
Car.remove whicheverCar.remove();
或者2-向ccar添加一个removeAllCars方法,当你调用[CCar removeAllCars]的时候会为你做这个。 ie 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]
没有明确的答案,但是如果你想推动一个类的方法来改善你的代码,那么请注意,一个类方法只会让你使用其他的类方法/variables。
类方法
是声明为静态的方法。 该方法可以在不创build类的实例的情况下被调用。 类方法只能对类成员进行操作,而不能对实例成员进行操作,因为类方法不了解实例成员。 除非在类的实例上调用类,否则类的实例方法也不能从类方法中调用。
实例方法
另一方面需要一个类的实例才能被调用,所以一个类的实例需要使用new关键字来创build。 实例方法对类的特定实例进行操作。 实例方法没有被声明为静态的。
在Objective-C中,所有方法都以“ – ”或“+”字符开头。 例:
@interface MyClass : NSObject // instance method - (void) instanceMethod; + (void) classMethod; @end
“+”和“ – ”字符分别指定方法是class method
还是instance method
。
如果我们调用这些方法,那么区别就很明显了。 这里的方法是在MyClass
中声明的。
instance method
需要该类的一个实例:
MyClass* myClass = [[MyClass alloc] init]; [myClass instanceMethod];
在MyClass
里面其他方法可以使用self
调用MyClass
实例方法:
-(void) someMethod { [self instanceMethod]; }
但是, class methods
必须在类本身上调用:
[MyClass classMethod];
要么:
MyClass* myClass = [[MyClass alloc] init]; [myClass class] classMethod];
这不会工作:
// Error [myClass classMethod]; // Error [self classMethod];
分类方法
类方法通常要么创build一个新的类的实例,要么检索类的一些全局属性。 类方法不能在一个实例上运行,也不能访问实例variables。
实例方法
实例方法在类的特定实例上运行。 例如,您实现的访问器方法都是实例方法。 您可以使用它们设置或获取特定对象的实例variables。
INVOKE
要调用实例方法,可以将消息发送到类的一个实例。
为了调用一个类方法,你直接把消息发送给类。
来源: IOS – Objective-C – 类方法和实例方法
类方法不能改变或知道任何实例variables的值。 这应该是知道实例方法是否可以是类方法的标准。
还记得,同样的想法适用于variables。 在讨论variables的时候,你会遇到类似于静态,成员,实例,类等的术语。
看来Obj-C社区里常见的术语是伊娃,例如variables,但我不是Obj-C的人。
上述答案的更新,我同意实例方法使用一个类的实例,而一个类方法只能用于类名称。
在Objective-C中存在自动引用计数之后,实例方法和类方法之间没有任何区别。
例如[NS StringWithformat:..]
一个类方法& [[NSString alloc] initwihtformat:..]
一个实例方法,两者在ARC之后是一样的
注意:这只是伪码格式
类方法
几乎所有它需要做的是在编译期间 。 它不需要任何用户input,也不需要计算它的实例。 关于它的一切都基于class级/蓝图 – 这是独一无二的,即你没有一个class级的多个蓝图。 在编译期间你可以有不同的变化吗? 不,所以这个类是唯一的,所以无论你调用一个类方法多less次,指向它的指针都是一样的。
PlanetOfLiving: return @"Earth" // No matter how many times you run this method...nothing changes.
实例方法
相反,实例方法是在运行时发生的,因为只有在这之后才创build了一个实例,这个实例在每个实例化时都会有所不同。
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,那么type方法和class方法是一样的。
添加到上面的答案
类方法将在类上工作,我们将用于通用的目的,像+ stringWithFormat,类的大小和最重要的是初始化等
NSString * str = [NSString stringWithFormat:@“%。02f %%”,someFloat];
实例方法将工作在一个不在类的类的实例,就像我们有两个人,我们想要知道每个单独的平衡,我们需要使用实例方法。 因为它不会返回一般的回应。 例如像确定NSSArray的计数等
[johnson getAccountBalance];
[ankit getAccountBalance];