zoukankan      html  css  js  c++  java
  • 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。子类可以重写父类的方法和属性。不详细说。

  • 相关阅读:
    postgresql----UNION&&INTERSECT&&EXCEPT
    postgresql----JOIN之多表查询
    postgresql----ANY/SOME&&ALL
    在页面获取本地电脑IP
    redis-Jedis连接集群
    redis-存储命令
    redis-启用命令
    springboot-整合freemarker
    springboot-发布jar包
    springboot-实现log4j的AOP切面
  • 原文地址:https://www.cnblogs.com/duyao/p/4923896.html
Copyright © 2011-2022 走看看