您的位置:首页 > 职场人生

黑马程序员——OC基础—核心语法(上)

2014-10-19 21:53 337 查看

----------------------Java培训、Android培训、iOS培训、.Net培训、期待与您交流!----------------------

=====类方法=====

类方法:使用类名来调用的方法.以+标记.使用场合:使用类方法代替对象方法可以提高性能.类方法比对象方法优化体现在不用创建对象就能执行行为.在内存中,+识别为类方法,直接去类的存储空间中调用方法.对象方法则需要通过对象指针访问对象,通过isa指针访问类空间,才能调用到方法.定义一个类方法:声明+实现
@interfacePerson:NSObject
//声明一个类方法
+(void)printClassName;
@end
@implementationPerson
//类方法的实现
+(void)printClassName{
NSLog(@"Class:Person");
}
@end
intmain(){
//使用类名来调用类方法
[PersonprintClassName];
return0;
}
+开头的方法和-开头的方法是不同的.类不能调用对象的方法,对象不能调用类的方法.否则(编译链接可以通过)运行时会报错-找不到相应的类/对象方法.
因为类方法和对象方法不同,所以可以有同名的类方法和对象方法.
+(void)test;
-(void)test;
上面两个方法是可以同时存在的.但是不能有两个同名的对象方法.
注意:成员变量也叫实例变量,是只有实例(对象)才有的变量,类没有成员变量.在内存中,对象里有存储空间存放成员变量的值,类的空间里是没有存放成员变量的地方的,所以类没有成员变量的值,类方法不能访问成员变量.
所以,如果方法中需要访问成员变量,就要写成对象方法.如果不需要访问成员变量,就可以写成类方法.
类方法的好处:不依赖于对象,执行效率高.能用类方法(不需要成员变量)尽量用类方法.
使用:当方法内部不需要访问成员变量时,就可以使用类方法.

=====self关键字的使用=====

self是个指针,指向调用它的变量(可能是类,也可能是对象).谁调用它,它就指向谁。
self关键字不以@开头.
1>使用self调用成员变量:
@interfacePerson:NSObject
{
int_age;
}
-(void)setAge:(int)age;
-(int)age;
-(void)printAge;
@end
在对象的方法里可以使用self关键字,self就指向调用这个方法的对象.
-(void)setAge:(int)age{
self->_age=age;//和_age=age;是等价的
}
2>使用self调用对象方法或者类方法:
-(void)bark{
NSLog(@"Woof!");
}
-(void)barkAndYell{
[selfbark];//使用self调用其它对象方法
NSLog(@"Wooooooool");
}
注意:1>注意如果在方法内部调用这个方法本身,会造成递归,可能会导致无限循环.
2>注意对象方法中的self代表对象,如果调用其它方法调用的是对象方法.类方法中的self代表调用的类,在类方法中使用self调用的是类方法.(Java中的this只能代表对象,不能代表类).对象方法中的self不能去调用类方法,类方法中的self不能去调用对象方法.
3>self不能去调用函数,函数只能通过函数名(参数)方式调用,不可以通过self调用.

=====构造方法=====

构造方法就是初始化对象的方法.
系统默认的方法为new方法,+new是一个类方法,用来创建一个对象,但是new方法把所有属性的值初始化为0,在开发中不常用.
new方法包括+alloc方法与-init方法,其中+alloc方法分配空间,-init方法初始化对象(系统默认值为0)。

===重写init方法===

init就是构造方法,用来初始化对象.构造方法是对象方法,因为它需要设置成员变量的值.
默认构造方法中所有的成员变量的值都设为0.我们想让新建对象时成员变量的默认值不是0,可以自己重写构造方法.
-init的方法是父类NSObject的方法.可以在子类中重写.
在类的实现中重写(重写方法可以不用声明,直接实现就可以)
@implementationPerson
-(id)init{
//必须要先调用父类的init方法进行初始化,因为父类中声明的成员变量子类也有,需要在init中初始化(比如把isa指针指向类).
self=[superinit];//初始化父类的成员变量,返回初始化好的对象
//判断是否初始化成功
if(self!=nil){
//给当前类的成员变量赋值
_age=20;
}
//返回已经初始化完毕的对象
returnself;
}
@end
也可以简写成如下形式:-(id)init{if(self=[superinit]){//调用父类方法初始化,并判断self是否有值_age=20;//给成员变量赋值}returnself;//返回初始化完毕的对象}这样写后,声明的Person类的年龄都是20。
重写init方法时,对象的成员变量初始值只能是固定的值.自定义构造方法可以在初始化时给成员变量赋不同的初值.
#自定义构造方法
自定义的构造方法需要声明和实现(重写父类的方法不需要声明)
自定义构造方法的规范:
1>是对象方法
2>返回值是id类型
3>方法名以init开头(方便程序员之间的交流,一看就知道是构造方法)
4>方法内部的格式和重写init的格式相同:调用super的方法并判断空值,给自己的成员变量赋值,返回对象
5>注意,如果有继承,通常只给自己的成员变量直接赋值,父类的成员变量通过调用父类的初始化方法对其赋值
@interfacePerson:NSObject
@propertyNSString*name;
@propertyintage;
//添加自定义构造方法
-(id)initWithName:(NSString*)name;
-(id)initWithName:(NSString*)nameandAge:(int)age;
@end
@implementationPerson
//重写init方法,默认名字为John
-(id)init{
if(self=[superinit]){
_name=@"John";
}
returnself;
}
//实现自定义的构造方法
-(id)initWithName:(NSString*)name{
if(self=[superinit]){//和重写init方法是同样的步骤
_name=name;
}
returnself;
}
-(id)initWithName:(NSString*)nameandAge:(int)age{
if(self=[superinit]){
_name=name;
_age=age;
}
returnself;
}
@end
intmain(){
Person*p=[[Personalloc]initWithName:@"Rose"andAge:18];//调用自己写的初始化方法新建对象
return0;
}
#子类对象的初始化#
比如,Student类是Person的子类,比Person类多了一个属性_no,我们想给Student添加初始化方法
@interfaceStudent:Person
@propertyintno;
-(id)initWithNo:(int)no;
-(id)initWithName:(NSString*)nameandAge:(int)ageandNo:(int)no;
@end
@implementationStudent
-(id)initWithNo:(int)no{
if(self=[superinit]){
_no=no;
}
returnself;
}
-(id)initWithName:(NSString*)nameandAge:(int)ageandNo:(int)no{
if(self=[superinit]){
_no=no;
//_name=name;错误.因为_name在父类中是@private,不可以通过_name访问
//[selfsetName:name];可以使用set方法设置,但是不建议
//self.age=age;也可以使用点语法,但是也不建议这样做
//如何合理的初始化父类提供的属性,最好使用父类的初始化方法,见下面
}
returnself;
}
@end
intmain(){
Student*s=[[Studentalloc]initWithNo:2];
return0;
}
新建Student对象并把学号赋值为2,会发现s的_name属性的值为"John",因为在Person的init方法中将_name默认值赋值为"John".
如果要给Student对象赋父类的成员变量值,不能直接使用父类的成员变量名(私有),要调用父类的set方法给成员变量赋值.但是不建议这么做.最好使用父类的初始化方法来初始化它提供的属性值:
-(id)initWithName:(NSString*)nameandAge:(int)ageandNo:(int)no{
if(self=[superinitWithName:nameandAge:age]){//调用父类的初始化方法
_no=no;
}
returnself;
}
这样写最好.父类的成员变量就使用父类的方法来给它初始化.自己的成员变量自己初始化.
这样的话,如果父类的init方法对成员变量的初始值有特别的设置或者筛选,那么子类的初始化方法里就不需要再写一遍,直接使用父类的初始化方法安全又方便.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: