扩大
缩小
  

03OC的类的补充

上一章我们介绍了类的定义,以及类的里面如何定义成员变量,如何定义方法等等。

一、self关键字

1.在C#中有关键字this表示当前对象,其实在OC中也有类似的关键字self,只是self关键字不仅表示当前对象还可以表示类本身,也就是说它既可以放在静态方法,又可以用在动态方法。

#import "Person.h"

@implementation Person
-(void)setName:(NSString *)name andAge:(int)age{
//    _name=name;
//    _age=age;
    self.name=name;
    self.age=age;
}

+(void)printInfo{
    NSLog(@"Hello,World!");
}

+(void)showMessage{
    [self printInfo];
}
@end

然后看看调用的时候:

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {

    Person *p=[[Person alloc]init];
    [p setName:@"Kenshin" andAge:28];
    [Person showMessage];
    
    return 0;
}

其中,setNameandAge是一个动态方法,这个时候self表示p这个对象,而showMessage代表的是调用的类,因此self为当前方法的调用者。

关于self的注意点:

#import "Person.h"

@implementation Person

-(void)setName:(NSString *)name{
    self.name=name;
}

这是一段实现属性的代码,self.name=name;其实就是调用self.setName=name;这样就会造成死循环。所以在没有用到@property自动生成的属性的时候,在定义成员变量的时候,都加上下划线。(_name好习惯)

二、构造函数

前面我们创建类的对象,在初始化的时候需要调用init方法(构造函数),下面我们看一喜爱自定义构造函数

实现代码:

//自定义构造方法
-(id)initWithName:(NSString *)name andAge:(int)age{
    if(self=[super init]){ //super代表父类
        self.name=name;
        self.age=age;
    }
    return self;
}

OC中super代表父类,通过调用父类的方法给当前对象赋值,然后判断这个对象是否为nil,如果不为空则依次给name、age属性赋值。

看看如何调用:

int main(int argc, const char * argv[]) {
   Person *p=[[Person alloc]initWithName:@"Kenshin" andAge:28]; NSLog(@"name=%@,age=%i",p.name,p.age); //结果:name=Kenshin,age=28 return 0; }

通过自定义构造方法固然可以简化代码,但是在使用时还要手动申请内存,在OC中一般我们通过定义一个静态方法来解决这个问题

//通过静态方法获得一个对象
+(id)personWithName:(NSString *)name andAge:(int)age{
    Person *p=[[Person alloc]initWithName:name andAge:age];
    return p;
}
int main(int argc, const char * argv[]) {
    
    Person *p=[[Person alloc]initWithName:@"Kenshin" andAge:28];
    NSLog(@"name=%@,age=%i",p.name,p.age);
    //结果:name=Kenshin,age=28
    
    Person *p2=[Person personWithName:@"Kaoru" andAge:27];
    NSLog(@"name=%@,age=%i",p2.name,p2.age);
    //结果:name=Kaoru,age=27
    return 0;
}

三、description方法

在C#每个类都有一个ToString()方法用于打印一个对象的信息、在OC中这个方法叫description,例如前面的Person类我们可以重写这个方法用于打印调试:

@implementation Person
-(NSString *)description{
    return [NSString stringWithFormat:@"{name:%@,age:%i}",self.name,self.age];
}
int main(int argc, const char * argv[]) {
    Person *p=[[Person alloc]init];
    p.name=@"Kenshin";
    p.age=28;
    NSLog(@"%@",p);//此时会调用对象description方法返回对应的描述信息
    /*结果:
     name:Kenshin,age:28}
     */
    return 0;
}

注意看NSLog的格式符为%@,当使用%@输出一个对象的时候,OC就会调用这个对象的description进行输出,默认情况下,我们不重写description方法时,输出内容应该为<类名:地址>例如:“<Person: 0x100202310>”千万不要在descripton中打印输出self,因为输出self的时候会调用该对象的descripton方法,这样一来就造成死循环。

四、继承

由于OC是面向对象语言,当然支持继承,其实我们的Persion已经继承了NSObject。子类可以重写父类的方法和属性。不详细说。

 

posted @ 2015-10-30 17:31  风筝遇上风  阅读(231)  评论(0编辑  收藏  举报