黑马程序员--OC自学笔记---05点语法、@property、@synthesize、动态类型、id类型、响应方法、构造方法
2015-12-30 09:25
676 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1. 点语法介绍和使用
1) 点语法是xcode的特性,当我们使用的时候,xcode会自动帮我们做一些替换操作。
2) 当类中设置了set和get方法后,在需要调用set和get方法的时候,可以使用 对象名.属性名 的方式来代替使用set和get方法,但是不能认为是直接获取属性值,而是xcode会把点语法替换成对应的set或get方法。
3) 以person类为例说明点语法:↓↓↓
4) 一般情况下,点语法出现在等号左侧为set方法,在等号右侧为get方法。
5) self使用点语法容易错的用法:
① 在set方法中使用点语法,误认为self和java中的this用法相同,这里的self.age其实是再次调用set方法(这里是-(void)setAge:(int)age)本身,所以会造成死循环。
② 在get方法中,同样把self当做this一样来使用,实际上self.age是调用get方法(这里是-(int)age)本身,也会造成死循环。
6) 点语法使用注意:点语法的本质是方法的调用,而不是访问成员变量,当使用点语法时,编译器会自动展开成相应的方法。切记点语法的本质是转换成相应的set和get方法,如果没有set和get方法,则不能使用点语法。
2. @property关键字
1) 概念:@property是编译器的指令,就是用来告诉编译器要做什么,@property告诉编译器声明属性的访问器(setter/getter)方法,这样可以免去我们手工去声明set和get方法
2) 使用格式:@property 数据类型 方法名(去掉set)
3) 作用:
① 在xcode 4.4之前,用于帮我们实现set/get方法的声明(没有实现)。
② 在xcode 4.4之后,有增强功能
4) @property只能写在@interface和@end之间
5) 告诉property要生成的get/set方法声明的成员变量的类型是什么
6) 告诉property要生成的get/set方法是哪个属性的,属性名称去掉下划线
7) 注意:用@property声明的方法名如果改变,则对应的实现方法的名称也必须改变,否则会出错。
3. @synthesize关键字
1) 是在.m文件中实现set和get方法
2) 格式为@synthesize 方法名
@synthesize name
等同于:-(void)setName:(NSString *)name{_name = name;}
-(NSString*)getName{return _name;}
3) 关于这个方法名的方法在.h文件中要先用@property声明
4) 如果使用@property和@synthesize的方法名在.h中没有声明,则系统会自动生成一个新的变量
5) 对指定的实例变量赋值:@synthesize 方法名 = 实例变量名
表示对指定的实例变量,实现其set/get方法,方法的名称为指定方法名,不再默认生成新的实例变量
@synthesize age=_age;
等号左侧的名称不管是什么,都是对等号右边的实例变量实现set/get方法。
4. @property的增强功能
举例说明:@property int age;
1) 在xcode4.4 以后,可以只使用@property而不使用@synthesize
2) @property会自动声明和实现_age的get和set方法
3) 操作的是带有下划线的对应实例变量,这里就是_age
4) 如果当前类没有定义带下划线的实例变量,系统会自动帮我们生成(系统自动定义一个int _age;)
5) 系统自动生成的实例变量是私有的,不能被子类继承。
6) Set和get方法在.m文件中可以自己手动实现,但是get和set方法不能同时手动实现
5. 动态类型和静态类型
多态:允许不同的类定义相同的方法
动态类型:程序直到执行时才能确定所属的类
静态类型:将一个变量定义为特定类的对象时,使用的是静态类型
使用动态类型进行编译时和运行时的检查。
6. id类型
1) id是一种通用的对象类型,它可以用来存储属于任何类的对象,也可以理解为万能指针
2) 在id的定义中,已经包好了*号,id指针只能指向OS的对象
3) NSObject和id都可以指向任何对象
4) NSObject对象会进行编译时检查(需要强制转换类型)
5) Id不需要强制类型转换,id可以直接使用
6) 编译器看到id以后,认为是动态类型,不再检查类型。
7) iOS5以后推出了instancetype类型,和id的异同:
① 都可以作为方法的返回类型
② Instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象
③ Instancetype只能作为返回值,不能像id那样作为参数
7. 动态类型检测
对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现。
1) 判断类型-(BOOL)isKindOfClass:classObj 判断实例对象是否是这个类或者这个类的子类的实例
使用格式:
[对象 isKindOfClass:类对象]
BOOL b = [dogisKindOfClass:[Animal class]]; //b=1;
2) -(BOOL)isMemberOfClass:classObj 判断实例对象是否是当前类的实例
格式为 [对象 isMembeOfClass: 类对象]
BOOL b = [dog isMemberOfClass:[Animalclass]];//b=0;
3) -(BOOL)isSubclassOfClass:classObj判断某个类是否是指定类的子类
格式为:[类名/类对象 isSubclassOfClass:类对象]
BOOL b =[Dog isSubclassOfClass:[Animal class]]; //b=1
8. 方法响应(调用)的检测
1) 判断实例对象能否响应(调用)制定的方法
-(BOOL)reapondsToSelector:(SEL)selector
格式:对象 respondsToSelector:方法的sel类型
举例:SEL s = @selector(run):
BOOL b = [ani rspondsToSelector:s];
判断ani能否调用run方法
2) 判断类能否响应指定的方法(即判断类是否有指定方法)
+(BOOL)instanceRespondToSelector:
BOOL b = [Dog instanceRespondToSelector:@selector(run)];
判断Dog类中是否有run方法。
9. 响应方法
1) -(id)performSelector:selector(应用selector指定的方法)
2) 通过performSelector调用无参方法
SEL s1 =@selector(eat);
Dog *dog = [Dog new];
[Dog performSelector:s1];
3) 通过performSelector调用一个参数的方法
SEL s2 =@selector(eat:);
[dog performSelector:s2 withObject:@”狗粮”];
4) 通过performSelector调用两个参数的方法
SEL s3 =@selector(eat: andFoodName);
[Dog performSelector:s3 withObject:@”大黄狗” withObject:@”狗粮”];
5) performSelector最多只能调用两个参数的方法。
10. 构造方法
1) 给对象进行初始化的方法为构造方法
2) OC中给对象进行初始化的方法是 init方法,init方法是一个对象方法,该方法返回的是一个对象(调用init方法的对象)
3) 关于alloc
① 想某个类发送alloc消息的结果
② 为该类分配内存,以存放该类的全部实例变量
③ 还将这块内存区域全部初始化为0
4) 注意:
① 个刚刚分配的对象并不能立即使用
② 需要县初始化该对象,然后才能使用它
③ 但由于未进行初始化,随后可能出现一些不可预测的行为
5) 重写构造方法init
初始化理论分析:
① [super init]的作用:面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化。
② self为什么要赋值为[super init]?
简单来说是为了防止父类的初始化方法release掉了self指向的空间并重新alloc了一块空间。这时的话,[superinit]可能alloc失败,这时就不再执行if中的语句。
③ super作为消息接收者的实质:
super并不是真正的指针,[super message]的实质是由self来接收父类的message。需要注意的是,[super message]中,message方法出现的self为[super message]语境中的self,即子类实例。
6) 自定义构造方法
① 一定是对象方法,以减号开头
② 返回值一般是id类型
③ 方法名一般以initWith开头
注意:
① 自己做自己的事情
② 父类的方法交给父类的方法来处理,子类的方法处理子类自己独有的属性
自定义构造方法应用:
1. 点语法介绍和使用
1) 点语法是xcode的特性,当我们使用的时候,xcode会自动帮我们做一些替换操作。
2) 当类中设置了set和get方法后,在需要调用set和get方法的时候,可以使用 对象名.属性名 的方式来代替使用set和get方法,但是不能认为是直接获取属性值,而是xcode会把点语法替换成对应的set或get方法。
3) 以person类为例说明点语法:↓↓↓
#import<Foundation/Foundation.h> @interfacePerson : NSObject { int _age; } -(void)setAge:(int)age; -(int)age; @end #import"Person.h" @implementationPerson -(void)setAge:(int)age{ _age = age; } -(int)age{ return _age; } @end #import<Foundation/Foundation.h> #import"Person.h" int main(intargc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; //[p setAge:15]; p.age = 15; //这里的点语法使用,掉用的是set方法,编译器会把这句话替换为上面的set方法的调用。 // NSLog(@"age = %d",[p age]); NSLog(@"age = %d",p.age);//这里的点语法,调用的是get方法,会自动的被替换为get方法的调用形式,和上面的输出语句是等同的。 } return 0; }
4) 一般情况下,点语法出现在等号左侧为set方法,在等号右侧为get方法。
5) self使用点语法容易错的用法:
① 在set方法中使用点语法,误认为self和java中的this用法相同,这里的self.age其实是再次调用set方法(这里是-(void)setAge:(int)age)本身,所以会造成死循环。
-(void)setAge:(int)age{ self.age = age; }
② 在get方法中,同样把self当做this一样来使用,实际上self.age是调用get方法(这里是-(int)age)本身,也会造成死循环。
-(int)age{ return self.age; }
6) 点语法使用注意:点语法的本质是方法的调用,而不是访问成员变量,当使用点语法时,编译器会自动展开成相应的方法。切记点语法的本质是转换成相应的set和get方法,如果没有set和get方法,则不能使用点语法。
2. @property关键字
1) 概念:@property是编译器的指令,就是用来告诉编译器要做什么,@property告诉编译器声明属性的访问器(setter/getter)方法,这样可以免去我们手工去声明set和get方法
2) 使用格式:@property 数据类型 方法名(去掉set)
3) 作用:
① 在xcode 4.4之前,用于帮我们实现set/get方法的声明(没有实现)。
② 在xcode 4.4之后,有增强功能
4) @property只能写在@interface和@end之间
5) 告诉property要生成的get/set方法声明的成员变量的类型是什么
6) 告诉property要生成的get/set方法是哪个属性的,属性名称去掉下划线
7) 注意:用@property声明的方法名如果改变,则对应的实现方法的名称也必须改变,否则会出错。
3. @synthesize关键字
1) 是在.m文件中实现set和get方法
2) 格式为@synthesize 方法名
@synthesize name
等同于:-(void)setName:(NSString *)name{_name = name;}
-(NSString*)getName{return _name;}
3) 关于这个方法名的方法在.h文件中要先用@property声明
4) 如果使用@property和@synthesize的方法名在.h中没有声明,则系统会自动生成一个新的变量
5) 对指定的实例变量赋值:@synthesize 方法名 = 实例变量名
表示对指定的实例变量,实现其set/get方法,方法的名称为指定方法名,不再默认生成新的实例变量
@synthesize age=_age;
等号左侧的名称不管是什么,都是对等号右边的实例变量实现set/get方法。
-(void)setAge:(int)age{ _age = age; } -(int)age{ return _age; }
4. @property的增强功能
举例说明:@property int age;
1) 在xcode4.4 以后,可以只使用@property而不使用@synthesize
2) @property会自动声明和实现_age的get和set方法
3) 操作的是带有下划线的对应实例变量,这里就是_age
4) 如果当前类没有定义带下划线的实例变量,系统会自动帮我们生成(系统自动定义一个int _age;)
5) 系统自动生成的实例变量是私有的,不能被子类继承。
6) Set和get方法在.m文件中可以自己手动实现,但是get和set方法不能同时手动实现
5. 动态类型和静态类型
多态:允许不同的类定义相同的方法
动态类型:程序直到执行时才能确定所属的类
静态类型:将一个变量定义为特定类的对象时,使用的是静态类型
使用动态类型进行编译时和运行时的检查。
6. id类型
1) id是一种通用的对象类型,它可以用来存储属于任何类的对象,也可以理解为万能指针
Animal *ani =[Animal new]; Dog * dog = [Dog new]; id = ani; id = dog;
2) 在id的定义中,已经包好了*号,id指针只能指向OS的对象
3) NSObject和id都可以指向任何对象
4) NSObject对象会进行编译时检查(需要强制转换类型)
5) Id不需要强制类型转换,id可以直接使用
6) 编译器看到id以后,认为是动态类型,不再检查类型。
7) iOS5以后推出了instancetype类型,和id的异同:
① 都可以作为方法的返回类型
② Instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象
③ Instancetype只能作为返回值,不能像id那样作为参数
7. 动态类型检测
对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现。
1) 判断类型-(BOOL)isKindOfClass:classObj 判断实例对象是否是这个类或者这个类的子类的实例
使用格式:
[对象 isKindOfClass:类对象]
BOOL b = [dogisKindOfClass:[Animal class]]; //b=1;
2) -(BOOL)isMemberOfClass:classObj 判断实例对象是否是当前类的实例
格式为 [对象 isMembeOfClass: 类对象]
BOOL b = [dog isMemberOfClass:[Animalclass]];//b=0;
3) -(BOOL)isSubclassOfClass:classObj判断某个类是否是指定类的子类
格式为:[类名/类对象 isSubclassOfClass:类对象]
BOOL b =[Dog isSubclassOfClass:[Animal class]]; //b=1
8. 方法响应(调用)的检测
1) 判断实例对象能否响应(调用)制定的方法
-(BOOL)reapondsToSelector:(SEL)selector
格式:对象 respondsToSelector:方法的sel类型
举例:SEL s = @selector(run):
BOOL b = [ani rspondsToSelector:s];
判断ani能否调用run方法
2) 判断类能否响应指定的方法(即判断类是否有指定方法)
+(BOOL)instanceRespondToSelector:
BOOL b = [Dog instanceRespondToSelector:@selector(run)];
判断Dog类中是否有run方法。
9. 响应方法
1) -(id)performSelector:selector(应用selector指定的方法)
2) 通过performSelector调用无参方法
SEL s1 =@selector(eat);
Dog *dog = [Dog new];
[Dog performSelector:s1];
3) 通过performSelector调用一个参数的方法
SEL s2 =@selector(eat:);
[dog performSelector:s2 withObject:@”狗粮”];
4) 通过performSelector调用两个参数的方法
SEL s3 =@selector(eat: andFoodName);
[Dog performSelector:s3 withObject:@”大黄狗” withObject:@”狗粮”];
5) performSelector最多只能调用两个参数的方法。
10. 构造方法
1) 给对象进行初始化的方法为构造方法
2) OC中给对象进行初始化的方法是 init方法,init方法是一个对象方法,该方法返回的是一个对象(调用init方法的对象)
3) 关于alloc
① 想某个类发送alloc消息的结果
② 为该类分配内存,以存放该类的全部实例变量
③ 还将这块内存区域全部初始化为0
4) 注意:
① 个刚刚分配的对象并不能立即使用
② 需要县初始化该对象,然后才能使用它
③ 但由于未进行初始化,随后可能出现一些不可预测的行为
5) 重写构造方法init
-(instancetype)init{ //先调用父类的初始化方法,完成默认的初始化操作 self = [super init]; //判断父类是否初始化成功 if (self) { //子类初始化的代码 _age = 10; } //self指代的是方法的调用者 return self; }
初始化理论分析:
① [super init]的作用:面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化。
② self为什么要赋值为[super init]?
简单来说是为了防止父类的初始化方法release掉了self指向的空间并重新alloc了一块空间。这时的话,[superinit]可能alloc失败,这时就不再执行if中的语句。
③ super作为消息接收者的实质:
super并不是真正的指针,[super message]的实质是由self来接收父类的message。需要注意的是,[super message]中,message方法出现的self为[super message]语境中的self,即子类实例。
6) 自定义构造方法
① 一定是对象方法,以减号开头
② 返回值一般是id类型
③ 方法名一般以initWith开头
注意:
① 自己做自己的事情
② 父类的方法交给父类的方法来处理,子类的方法处理子类自己独有的属性
自定义构造方法应用:
//父类Person类 #import<Foundation/Foundation.h> @interfacePerson : NSObject @property intage; @propertyNSString *name; -(instancetype)initWithName:(NSString*)name andAge:(int)age; @end #import"Person.h" @implementationPerson -(instancetype)initWithName:(NSString*)name andAge:(int)age{ if(self = [super init]){ _name = name; _age = age; } return self; } @end //子类Student类 #import"Person.h" @interfaceStudent : Person @property intsno; -(instancetype)initWithName:(NSString*)name andAge:(int)age andSno:(int)sno; @end #import"Student.h" @implementationStudent -(instancetype)initWithName:(NSString*)name andAge:(int)age andSno:(int)sno{ if (self = [super initWith:nameandAge:age]) { _sno = sno; } return self; } @end //主函数 #import<Foundation/Foundation.h> #import"Student.h" int main(intargc, const char * argv[]) { @autoreleasepool { Student *stu = [[Studentalloc]initWithName:@"cjk" andAge:38 andSno:438]; NSLog(@"name = %@,age = %d,sno =%d",stu.name,stu.age,stu.sno); } return 0; }
相关文章推荐
- iOS面试3
- 程序员经常说的二十多句话,吐槽吧程序员!
- 程序员经常说的二十多句话,吐槽吧程序员!
- 程序员经常说的二十多句话,吐槽吧程序员!
- 程序缘,程序媛,程序员-2015年年终总结
- 程序员生存定律--成长路上常见的坑
- 程序员生存定律--管理向左,技术向右
- 月薪3万的程序员都避开了哪些坑
- 在程序员联盟除了编程,你还能学到这些
- 【程序员】区区英语算什么,还搞不定了?
- 【程序员游学记】卢浮宫与虚拟现实
- 从扎克伯格捐450亿看程序员前景
- 在程序员联盟除了编程,你还能学到这些
- 【程序员】区区英语算什么,还搞不定了?
- 【程序员游学记】卢浮宫与虚拟现实
- 程序员如何谋划出月薪3万
- 程序员入行门槛真的那么低吗?
- 程序员『青春饭』问题之我见
- 一个40岁程序员的无奈
- 程序员遇到BUG后,最好的方法是?