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

黑马程序员--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类为例说明点语法:↓↓↓

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: