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

一、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。子类可以重写父类的方法和属性。不详细说。

03OC的类的补充的更多相关文章

  1. C++笔记006:关于类的补充

    原创笔记,转载请注明出处! 点击[关注],关注也是一种美德~ 关于类的补充: 类是一个数据类型(固定大小内存块的别名),定义一个类,是一个抽象的概念,不会给你分配内存,用数据类型定义变量的时候,才会分 ...

  2. python day 11: 类的补充,元类,魔法方法,异常处理

    目录 python day 11 1. 类的补充 1.1 通过反射来查找类,创建对象,设置对象的属性与方法 1.2 类的魔法方法:getitem,setitem 1.3 元类__metaclass__ ...

  3. day13 类的补充

    访问修饰符                          同包                          不同包 本类         子类         非子类        子类   ...

  4. Spring框架 全注解annotation不使用配置文件(SpringConfiguration.java类代替) 补充 xml配置文件没有提示解决

    全注解不使用配置文件 首先还是倒包 在原有的jar包: 需Spring压缩包中的四个核心JAR包 beans .context.core 和expression 下载地址: https://pan.b ...

  5. CSS3结构类选择器补充

    :empty 没有子元素(包括文本节点)的元素 :not  否定选择器 <!DOCTYPE html> <html lang="en" manifest=&quo ...

  6. idea 新建java类自动补充创建人,创建时间,版本等..

    1.先进入 File 2.进入 Editor 找到 File and Code Templates 并点击 3.右侧点击 lncludes  4.第二项 File Header  /** * @aut ...

  7. UML从需求到实现---类图(2)

    上节写到了UML中的类图:UML从需求到实现---类图(1) 写完以后总觉得写的不够详细.里面很多细节没有说到.一篇文章就把强大的面向对象的类说完.当然是不可能的.这次我再补充一些关于UML中类图和类 ...

  8. C++类(Class)总结

    ---恢复内容开始--- 一.C++类的定义     C++中使用关键字 class 来定义类, 其基本形式如下:class 类名{ public: //行为或属性  protected: //行为或 ...

  9. JAVA不可变类与可变类、值传递与引用传递深入理解

    一个由try...catch...finally引出的思考,在前面已经初步了解过不可变与可变.值传递与引用传递,在这里再次深入理解. 1.先看下面一个try..catch..finally的例子: P ...

随机推荐

  1. rpc框架之 thrift连接池实现

    接前一篇rpc框架之HA/负载均衡构架设计 继续,写了一个简单的thrift 连接池: 先做点准备工作: package yjmyzz; public class ServerInfo { publi ...

  2. 关于javascript中apply()和call()方法的区别

    如果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可理喻.如果在学JavaScript这自由而变幻无穷的语 ...

  3. 栈的理解以及如何计算程序所需栈的大小并在IAR中设置栈

    文章首发于浩瀚先森博客 #栈的理解 一个程序大体上讲都是由变量和函数组合而成,变量有全局变量和局部变量,还有函数间传值的参数以及返回值. Stack是为了程序运行过程中临时保存所需数据而在内存里分配的 ...

  4. 初次尝试用Kotlin实现Android项目

    Kotlin: The Swift of Android 起这个文内标题的原因很简单,就是对Kotlin抱有希望--能使Android的开发更简洁.高效及安全.知道Kotlin是从简书的一篇短文,越来 ...

  5. 1125MySQL Sending data导致查询很慢的问题详细分析

    -- 问题1 tablename使用主键索引反而比idx_ref_id慢的原因EXPLAIN SELECT SQL_NO_CACHE COUNT(id) FROM dbname.tbname FORC ...

  6. Android异步消息处理机制完全解析,带你从源码的角度彻底理解(转)

    开始进入正题,我们都知道,Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃.相信大家在日常的工作当中都会经常遇到这个问题,解决的方案应该也是早已烂熟于心,即创建一 ...

  7. 【USACO 2.4】The Tamworth Two

    题意:C代表cows,F代表farmer,一开始都向北,每分钟前进1步,如果前方不能走,则这分钟顺时针转90°,问多少步能相遇,或者是否不可能相遇,10*10的地图. 题解:dfs,记录状态,C和F的 ...

  8. Matplotlib 学习笔记

    注:该文是上了开智学堂数据科学基础班的课后做的笔记,主讲人是肖凯老师. 数据绘图 数据可视化的原则 为什么要做数据可视化? 为什么要做数据可视化?因为可视化后获取信息的效率高.为什么可视化后获取信息的 ...

  9. UIView的setNeedsDisplay和setNeedsLayout

    1,UIView的setNeedsDisplay和setNeedsLayout方法 首先两个方法都是异步执行的.而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到  UI ...

  10. reGeorg v1.0内网流量转发

    reGeorg v1.0 git Usage $ reGeorgSocksProxy.py [-h] [-l] [-p] [-r] -u [-v] Socks server for reGeorg H ...