类方法和实例方法有什么区别?
实例方法是访问器(getter和setter),而类方法几乎是其他所有方法吗?
#1楼
实例方法适用于类的实例(即对象),而类方法适用于类本身。
在C#中,类方法标记为静态。 未标记为static的方法和属性是实例方法。
class Foo {
public static void ClassMethod() { ... }
public void InstanceMethod() { ... }
}
#2楼
Instances方法对类的实例(即“对象”)进行操作。 类方法与类相关联(大多数语言对这些人使用关键字static
)。
#3楼
您的问题的答案并非特定于objective-c,但是在不同的语言中,Class方法可能被称为静态方法。
类方法和实例方法之间的区别是
类方法
- 对类变量进行操作(它们无法访问实例变量)
- 不要求实例化对象
- 有时可能是代码气味(一些不熟悉OOP的人用作在OO环境中进行结构化编程的拐杖)
实例方法
- 对实例变量和类变量进行操作
- 必须有一个instanciated对象来操作
#4楼
像大多数其他答案所说的那样,实例方法使用类的实例,而类方法只能使用类名。 在Objective-C中,它们是如此定义的:
@interface MyClass : NSObject
+ (void)aClassMethod;
- (void)anInstanceMethod;
@end
然后可以这样使用它们:
[MyClass aClassMethod];
MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];
一些真实的类方法示例是许多Foundation类的便捷方法,如NSString
的+stringWithFormat:
或NSArray
的+arrayWithArray:
. 实例方法是NSArray
的-count
方法。
#5楼
与其他答案一样,实例方法对一个对象进行操作并可以访问其实例变量,而一个类方法作为一个整体对一个类进行操作,并且无法访问特定实例的变量(除非您将该实例作为一个参数)。
类方法的一个很好的例子是计数器类型方法,它返回类的实例总数。 类方法以+
开头,而实例以-
开头。 例如:
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
这需要一个对象,将它放在一个数组中,并返回一个不需要内存管理的自动释放版本的数组,非常适合temperorary数组,什么不是。
我希望你现在明白何时和/或为什么你应该使用类方法!!
#6楼
类方法
是声明为静态的方法。 可以在不创建类的实例的情况下调用该方法。 类方法只能在类成员上操作,而不能在实例成员上操作,因为类方法不知道实例成员。 除非在该类的实例上调用类,否则也不能从类方法中调用类的实例方法。
实例方法
另一方面,在调用类之前需要该类的实例存在,因此需要使用new关键字创建类的实例。 实例方法对特定的类实例进行操作。 实例方法未声明为静态。
#7楼
我认为理解这一点的最好方法是查看alloc
和init
。 正是这种解释让我理解了这些差异。
类方法
类方法作为一个整体应用于类。 如果检查alloc
方法,那就是在方法声明之前用+
表示的类方法。 它是一个类方法,因为它应用于类来创建该类的特定实例。
实例方法
您使用实例方法来修改该实例唯一的特定类实例,而不是整个类。 init
(例如,在方法声明之前用-
表示)是一个实例方法,因为在使用alloc
创建该类之后,通常会修改该类的属性。
例
NSString *myString = [NSString alloc];
您正在调用类方法alloc
以生成该类的实例。 注意消息的接收者是一个类。
[myString initWithFormat:@"Hope this answer helps someone"];
您正在通过在该实例上设置一些属性来修改名为myString
的NSString
实例。 注意消息的接收者是一个实例(类NSString
对象)。
#8楼
对上述答案的更新,我同意实例方法使用类的实例,而类方法可以只使用类名。
在Objective-C中存在自动引用计数后,实例方法和类方法之间没有任何区别。
例如[NS StringWithformat:..]
一个类方法& [[NSString alloc] initwihtformat:..]
一个实例方法,在ARC之后都是相同的
#9楼
所有技术细节都在其他答案中得到了很好的介绍。 我只是想分享一个简单的类比,我认为很好地说明了类和实例之间的区别:
一个类就像一个房子的蓝图 :你只有一个蓝图,而且(通常)你不能单独用蓝图做那么多。
实例 (或对象 )是您根据蓝图构建的实际房屋 :您可以使用相同的蓝图构建大量房屋。 然后,您可以在每个房屋中为墙壁绘制不同的颜色,就像您可以独立更改类的每个实例的属性而不影响其他实例一样。
#10楼
所以如果我理解正确的话。
class
方法不需要您分配该对象的实例来使用/处理它。 class
方法是自包含的,并且可以在不依赖于该类的任何对象的状态的情况下操作。 class
方法应该为所有自己的工作分配内存并在完成时释放,因为该类的任何实例都不能释放先前调用类方法时分配的任何内存。
instance
方法恰恰相反。 除非您分配该类的实例,否则无法调用它。 它就像一个普通的类,它有一个构造函数,可以有一个析构函数(清理所有分配的内存)。
最有可能(除非您正在编写可重用的库,否则您不需要class
变量。
#11楼
在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];
#12楼
类方法
类方法通常要么创建类的新实例,要么检索类的某些全局属性。 类方法不对实例操作或对实例变量具有任何访问权限。
实例方法
实例方法对类的特定实例进行操作。 例如,您实现的访问器方法都是实例方法。 您可以使用它们来设置或获取特定对象的实例变量。
INVOKE
要调用实例方法,请将消息发送到类的实例。
要调用类方法,请直接将消息发送给类。
来源: IOS - Objective-C - 类方法和实例方法
#13楼
注意:这只是伪代码格式
类方法
几乎所有它需要做的就是在编译期间 。 它不需要任何用户输入,也不需要基于实例的计算。 关于它的一切都基于类/蓝图 - 这是唯一的,即你没有一个类的多个蓝图。 编译时可以有不同的变化吗? 不,因此该类是唯一的,因此无论您调用类方法多少次,指向它的指针都是相同的。
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,则类型方法与类方法相同。
#14楼
类方法通常用于创建该类的实例
例如, [NSString stringWithFormat:@"SomeParameter"];
返回一个NSString
实例,其中包含发送给它的参数。 因此,因为它是返回其类型对象的Class方法,所以它也称为便捷方法。
#15楼
添加到上面的答案
类方法将在类上工作,我们将其用于通用目的,例如+ stringWithFormat,类的大小,最重要的是用于init等
NSString *str = [NSString stringWithFormat:@"%.02f%%",someFloat];
Instance方法将处理一个不在类上的类的实例,就像我们有两个人一样,我们希望在这里分别知道每个的平衡,我们需要使用实例方法。 因为它不会返回一般回复。 例如确定NSSArray的数量等。
[johnson getAccountBalance];
[ankit getAccountBalance];
#16楼
类方法不能更改或知道任何实例变量的值。 这应该是了解实例方法是否可以是类方法的标准。
#17楼
例如,一个游戏中产生了大量的汽车......每个都属于CCar类。 当汽车被实例化时,它会打电话给
[CCar registerCar:self]
所以CCar类可以列出每个CCar实例化的列表。 假设用户完成一个级别,并且想要删除所有汽车...您可以:1-浏览您手动创建的每个CCar的列表,并执行whicheverCar.remove();
Car.remove whicheverCar.remove();
或者2-添加一个removeAllCars方法给CCar,当你调用[CCar removeAllCars]时,它会为你做这个。 即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]
没有明确的答案,但是如果你觉得推动一个类方法会改进你的代码,试一试,并记住一个类方法只允许你使用其他类方法/变量。
#18楼
还记得,同样的想法适用于变量。 在谈论与方法/函数相同的变量时,您会遇到静态,成员,实例,类等术语。
似乎Obj-C社区中的常用术语是ivar,例如变量,但我还不是Obj-C家伙。
asdfgh0077 发布了0 篇原创文章 · 获赞 2 · 访问量 7151 私信 关注