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

一、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:];
[Person showMessage]; return ;
}

其中,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:];
NSLog(@"name=%@,age=%i",p.name,p.age);
//结果:name=Kenshin,age=28 Person *p2=[Person personWithName:@"Kaoru" andAge:];
NSLog(@"name=%@,age=%i",p2.name,p2.age);
//结果:name=Kaoru,age=27
return ;
}

三、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=;
NSLog(@"%@",p);//此时会调用对象description方法返回对应的描述信息
/*结果:
name:Kenshin,age:28}
*/
return ;
}

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

四、继承

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

最新文章

  1. 深入研究Visual studio 2017 RC新特性
  2. 转:对TCP/IP网络协议的深入浅出归纳
  3. Oracle数据库和DB2数据库分页SQL的区别举例
  4. APNS IOS PHP 苹果推送
  5. cocos2d-x触摸事件优先级的探究与实践
  6. POJ 2886 Who Gets the Most Candies? 线段树
  7. bzoj4003
  8. Document原来可以这样来获取DOM
  9. Linux 编程学习笔记----命令行参数处理
  10. 【原创】大数据基础之Spark(3)Spark Thrift实现原理及代码实现
  11. gulp打开gbk编码的html文件乱码
  12. 小程序getLocation出现的各种问题汇总
  13. Html 标签种类
  14. centos7 rpm 安装mysql
  15. 1032. Sharing (25)
  16. python2和python3的内存使用情况
  17. Swift 并行编程现状和展望 - async/await 和参与者模式
  18. [leetcode]Spiral Matrix @ Python
  19. C++课程小结 继承与派生
  20. MongoDB(课时5 数据查询)

热门文章

  1. 原创jquery插件treeTable(转)
  2. 验证LeetCode Surrounded Regions 包围区域的DFS方法
  3. C#进阶系列——动态Lamada
  4. manachor
  5. 【Python】[面向对象高级编程] 多成继承,定制类,使用枚举
  6. Curl扩展开启失败解决方案
  7. 基于NFS的分布式持久化
  8. the pipeline of call SNP
  9. JAVA之IO流(字节流)
  10. AOJ DSL_2_C Range Search (kD Tree)