看官们,我们在前面章回中介绍面向对象的知识时总有一个绕不开的内容:NSObject
,本章回中将详细它。
在OC中,NSObject
是所有类的根类,这点我们在前面章回中的示例代码中可以看到,作为根类它提供了一些最基础的功能:
初始化,输出类中成员的明细和比较对象是否相同.
这些功能通过具体的方法来体现,它们是:init, description,isEquals
.接下来我们详细分析如何使用这三个方法。
- init方法用来做初始化,如果有专门的内容需要初始化,那么就重写此方法,否则直接使用父类的方法就可以;
- description方法用来输出类中成员的明细,如果不重写此方法默认输出对象地址,另外输出的明细有专门的格式,参考示例代码就可以;
- isEquals用来比较对象是否相等,默认情况下比较两个对象的地址是否相等,子类中一定要重写此方法,不然会得到错误的结果;
下面我们通过具体的代码来演示如何使用这些方法:
#import<Foundation/Foundation.h>
@interface Phone : NSObject
@property NSString *name;
@property int size;
-(void) show;
@end
@implementation Phone
@synthesize name;
@synthesize size;
-(instancetype) init {
self = [super init];
if(self) {
name = @"This is Phone";
size = 123;
}
return self;
}
-(void) show {
NSLog(@"name: %@, size: %d ",name,size);
}
-(NSString*) description {
return [NSString stringWithFormat:@"<Phone[name=%@,size=%d]>",name,size];
}
-(bool) isEquals: (id) object {
bool result = NO;
if(self != nil && object == nil)
return result;
if(self == object)
return YES;
if([name isEqualToString:[object name]] && size == [object size])
result = YES;
return result;
}
@end
int main() {
Phone *p1 = [[Phone alloc] init];
Phone *p2 = [[Phone alloc] init];
Phone *p3 = [[Phone alloc] init];
Phone *p4 = p1;
[p1 setName:@"this is p1"];
[p2 setName:@"this is p2"];
[p3 setName:@"this is p1"];
NSLog(@"OBJ:%@",[p1 description]);
NSLog(@"OBJ:%@",[p2 description]);
NSLog(@"OBJ:%@",[p3 description]);
NSLog(@"OBJ:%@",[p4 description]);
if([p1 isEquals:p2])
NSLog(@"p1 == p2");
else
NSLog(@"p1 != p2");
if([p1 isEquals:p3])
NSLog(@"p1 == p3");
else
NSLog(@"p1 != p3");
if(p1 == p3)
NSLog(@"p1 == p3");
else
NSLog(@"p1 != p3");
if([p1 isEquals:p4])
NSLog(@"p1 == p4");
else
NSLog(@"p1 != p4");
if(p1 == p4)
NSLog(@"p1 == p4");
else
NSLog(@"p1 != p4");
}
在代码中,我们定义了Phone类,它继承自NSObject,包含两个属性和一个方法;实现该类的时候,除了实现类自己的方法:Show外,它还实现了父类中的三个方法。接下来我们依次分析这三个方法的实现思路:
- init方法首先调用了父类的init方法,然后初始化类的两个属性,最后返回初始化后的对象;
- description方法用来输出类中成员的明细,代码中使用了固定的格式字符串来输出明细;
- isEquals用来比较对象是否相等,我们提供的实现中先比较对象的地址是否相等,如果地址相等那么两个对象肯定相等。 如果地址不相等,那么再比较对象的属性值是否相等,此时,如果两个对象的属性值都相等,那么这两个对象相等。
最后,我们在main方法来使用这三个方法。首先创建了p1,p2,p3,p4四个Phone类型的对象,这其中使用了Phone类的init方法.接着在代码中使用description方法分别输出了这四个对象的内容,从对象的内容上看,只有p2的内容和其它几个对象的内容不一样。由此可见p1,p3,p4这三个对象是相等的,在接下来的代码中使用isEquals方法进行了验证。下面是程序的运行结果,请大家参考:
1 ex.out[2901:62466] OBJ:<Phone[name=this is p1,size=123]>
2 ex.out[2901:62466] OBJ:<Phone[name=this is p2,size=123]>
3 ex.out[2901:62466] OBJ:<Phone[name=this is p1,size=123]>
4 ex.out[2901:62466] OBJ:<Phone[name=this is p1,size=123]>
5 ex.out[2901:62466] p1 != p2
6 ex.out[2901:62466] p1 == p3
7 ex.out[2901:62466] p1 != p3
8 ex.out[2901:62466] p1 == p4
9 ex.out[2901:62466] p1 == p4
从程序的运行结果中可以看到,程序对各个对象是否相等的判断结果和我们人工判断的结果保持一致。另外,在程序中我们为了突出重写isEquals方法的重要性,我们使用==来判断两个对象是否相等,该运算符只能判断两个对象的地址是否相等,也就是说它和isEquals方法默认的判断方法相同,从运算结果中的第7行可以看到,如果不重写isEquals方法,程序会认为p1与p3不相等,这显然不符合实际情况,我们从运行结果的第1行和第3行可以看到p1和p3是相等的。
最后,我们对本章回的内容做一个总结:
- 1.OC中所有类的根类为NSObject;
- 2.NSObject类提供了三个方法:init, description,isEquals.
- 3.init方法用来初始化类中的各种属性;
- 4.description方法用来输出类中成员的明细;
- 5.isEquals用来比较对象是否相等,而不是使用等号来比较;
- 6.我们在定义的类的时候最好重写最后两个方法,第一个方法可以依据类的属性来决定是否重写;
看官们,欲知后事如何且听下回分解!