黑马程序员--OC自学笔记---05点语法、@property、@synthesize、动态类型、id类型、响应方法、构造方法

------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)        点语法使用注意:点语法的本质是方法的调用,而不是访问成员变量,当使用点语法时,编译器会自动展开成相应的方法。切记点语法的本质是转换成相应的setget方法,如果没有setget方法,则不能使用点语法。

 

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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bright1st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值