每一个实例变量定义两个方法:设置变量的setter方法 获取变量值的getter方法
set方法的书写规范
-
set方法一定是一个对象方法
-
set方法一定不能有返回值
-
set方法必须以set开头
-
set之后跟的是 实例变量去掉下划线,并且首字母大写
-
set方法一定有参数,而且参数的类型和实例变量的类型一致
-
set方法的形参名 一般是 去掉下划线的实例变量名
-
形参名不能和 实例变量名同名
-
set方法实现中,一定要用形参给实例变量赋值
get方法的书写规范
-
get方法一定是一个对象方法
-
get方法一定有返回值,返回值的类型和实例变量的类型要一致
-
get方法的方法名 是去掉下划线的实例变量名
-
get方法一定没有参数
-
get方法的实现中,一定是返回实例变量值
下面演示set和get方法的代码
我们创建一个Person类在.h文件中的代码如下:
#import <Foundation/Foundation.h> @interface Person : NSObject { NSString *_name; int _age; } // 成员变量_name的setter方法和getter方法的声明 - (void)setName:(NSString *)name; - (NSString *)name; // 成员变量_age的setter方法和getter方法的声明 - (void)setAge:(int)age; - (int)age; @end
.m文件中的代码如下:
#import "Person.h" @implementation Person // 成员变量_name的setter方法和getter方法的实现 - (void)setName:(NSString *)name { _name = name; } - (NSString *)name { return _name; } // 成员变量_age的setter方法和getter方法的实现 - (void)setAge:(int)age { //在这可以限制输入的年龄是否合法 if (age >= 18) { _age = age; } else { _age = 18; } } - (int)age { return _age; } @end
OC中没有方法的重载,所谓的参数多一个是因为方法的名称变了,提示:do: : : :
OC中static关键字的使用:唯一要注意的是成员变量不能定义成static,其它时候的使用跟C语言中一样,请看我之前的博客 >---点我就能看到---<
OC中的self关键字,self用到类方法中代表本类,self用到对象方法中表示这个对象
self修饰变量:会访问成员变量请看代码:(依然根据Person类)在.m文件中
// 成员变量_name的setter方法和getter方法的实现 - (void)setName:(NSString *)name { self->speed = speed; // self->speed等价于_name // _name = name; } - (NSString *)name { return _name; }
这里再次说一下关于面对对象的四大特性分别为
1.抽象 2.封装 3.继承 4.多态
抽象性:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。比如,我们要设计一个学生成绩管理系统,考察学生这个对象时,我们只关心他的班级、学号、成绩等,而不用去关心他的身高、体重这些信息。抽象包括两个方面,一是过程抽象,二是数据抽象。过程抽象是指任何一个明确定义功能的操作都可被使用者看作单个的实体看待,尽管这个操作实际上可能由一系列更低级的操作来完成。数据抽象定义了数据类型和施加于该类型对象上的操作,并限定了对象的值只能通过使用这些操作修改和观察。
有关于封装,继承,多态请看我之前的博客(还介绍了分类) >---请点击这里---<
成员变量修饰符的介绍
- @public 公开的, 在任何地方通过实例对象都可以访问
-
@private 私有的,表示只能在当前类中使用 不可以在子类中使用 但是被子类继承的
-
@protected 受保护类型,表示只能在当前类和子类中访问(默认是protected)
description方法:重写父类的description方法可以改变NSLog的输出
如果在-description方法中使用NSLog打印self 会造成死循环
代码如下
//重写父类的description -(NSString *)description{ // do something.... // 例如 return [NSString stringWithFormat:<#(NSString *), ...#>]; }
类的本质是对象
类对象属于Class类型
// 获取类对象的2种方式 Class c = [Person class]; // 类方法 // 或者 Person *p = [Person new]; Class c2 = [p class]; // 对象方法
类方法中不能调用成员变量
SEL
1.方法的存储位置
- 每个类的方法列表都存储在类对象中
- 每个方法都有一个与之对应的SEL类型的对象
- 根据一个SEL对象就可以找到方法的地址,进而调用方法
- SEL类型的定义
typedef struct objc_selector *SEL;
2.SEL对象的创建
SEL s = @selector(test); SEL s2 = NSSelectorFromString(@"test");
3.SEL对象的其他用法
// 将SEL对象转为NSString对象 NSString *str = NSStringFromSelector(@selector(test)); Person *p = [Person new]; // 调用对象p的test方法 [p performSelector:@selector(test)];
OC中的点语法 是Xcode的特性,Xcode帮我们做代码替换
// Xcode会帮我们把下面的代码替换成[person setAge:18]; person.age = 18; // Xcode会帮我们把下面的代码替换成[person age]; int a = person.age;
@property 和 @synthesize
@property 编译器指令,编译器帮我们会进行_age _name get/set方法的声明
@synthesize帮我们实现了 实例变量的get和set方法
Xcode4.4之后@property既可以帮我进行_age _name get/set方法的声明,也可以实现实例变量的get和set方法
@property (nonatomic, assign) int age; @property (nonatomic, copy) NSString *name;
id是万能指针,可以指向任何对象
OC中的构造方法
重写构造方法,让对象创建成功后,就有初始的值
OC中给对象进行初始化的方法是:init对象方法 该方法返回的是一个对象(调用init方法的对象)
// 当子类把父类的init覆盖了,这是默认的先执行子类的 - (instancetype)init{ //先让父类把父类原来做的事情做完 self = [super init]; //判断父类是否初始化成功 if (self) { //此处写子类初始化的内容 _age = 18; //给年龄设置为默认值 18岁 } return self; //self指代的事方法的调用者 }
自定义构造方法
.h文件代码如下
#import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatomic, copy) NSString* name; @property (nonatomic, assign) int age; // 自定义构造方法 - (instancetype)initWithName:(NSString *)name andAge:(int)age; @end
.m文件代码如下
#import "Person.h" @implementation Person - (instancetype)initWithName:(NSString *)name andAge:(int)age{ if (self = [super init]) { _name = name; _age = age; } return self; } @end