标签:
- set方法和get方法
- set方法和get方法的使用场合
@public的成员可以被随意赋值,应该使用set方法和get方法来管理成员的访问(类似机场的安检、水龙头过滤,过滤掉不合理的东西),比如僵尸的生命值不能为负数
- set方法
- 作用:用来设置成员变量,可以在方法里面过滤掉一些不合理的值
- 命名规范:
- 方法都是以set开头,而且后面跟上成员变量名,成员变量名的首字母必须大写
- 形参名称不要跟成员变量同名
- get方法
- 作用:返回对象内部的成员变量
- 命名规范:get方法的名称一般就跟成员变量同名
- 成员变量的命名规范
- 成员变量都以下划线 _ 开头
- 可以跟get方法的名称区分开
- 可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量
- 代码示例
#import <Foundation/Foundation.h>
// 声明
@interface Car : NSObject
{
int _wheels; // 轮子个数
}
/*set方法*/
- (void) setWheels:(int)wheels;
/*get方法*/
- (int) wheels;
@end
@implementation Car
// set方法的实现
- (void) setWheels:(int)wheels
{
// 对外面传进来的轮子数进行过滤
if (wheels<=0)
{
wheels = 1;
}
_wheels = wheels;
}
// get方法的实现
- (int) wheels
{
return _wheels;
}
@end
- 封装的好处
- 过滤不合理的值
- 屏蔽内部的赋值过程
- 让外界不必关注内部的细节
- 练习
- Dog类,属性:weight、speed,方法:吃、跑
- Person类,属性:dog、age,方法:喂狗、遛狗
- 类方法
- 基本概念
直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)
- 类方法和对象方法对比
- 对象方法
- 以减号-开头
- 只能让对象调用,没有对象,这个方法根本不可能被执行
- 对象方法能访问实例变量(成员变量)
- 类方法
- 以加号+开头
- 只能用类名调用,对象不能调用
- 类方法中不能访问实例变量(成员变量)
- 使用场合:当不需要访问成员变量的时候,尽量用类方法
- 类方法和对象方法可以同名
- 示例
- self关键字
- 成员变量和局部变量同名
- 当成员变量和局部变量同名时,采取就近原则,访问的是局部变量
- 用self访问成员变量,区分同名的局部变量
- 使用细节
- 出现的地方:所有的OC方法中(对象方法\类方法),不能出现在函数
- 作用
- 使用 "self->成员变量名" 访问当前方法调用的成员变量
- 使用 "[self 方法名];" 来调用方法(对象方法\类方法)
- 常见错误
- 低级错误:用self去调用函数
- 类方法中用self调用对象方法,对象方法中用self调用类方法
- self死循环
- 示例
- 狗在跑之前叫两声
- 计算器类,计算平均值的调用求和方法
- 点语法
- 利用点语法替换set方法和get方法
Student *stu = [Student new];
[stu setAge:100];
int age = [stu age];
stu.age = 100;
int age = stu.age;
- 点语法的本质
- 其实点语法的本质还是方法调用
- 当使用点语法时,编译器会自动展开成相应的方法
- 死循环注意
- (void) setAge:(int)age {
// 下面的代码会引发死循环
self.age = age;
}
- (int) age {
// 下面的代码会引发死循环
return self.age;
}
- 成员变量的作用域
- 基本概念
局部变量、全局变量都有自己的作用域,成员变量也不例外
- 类型
- @private:只能在当前类的对象方法中直接访问
- @protected:可以在当前类以及子类的对象方法中直接访问
- @public:任何地方都可以直接访问
- @package:同一个“体系内”(框架)可以访问,介于@private和@public之间
- 继承补充
- 父类\超类 superclass
- 子类 subclass\subclasses
- @implementation补充
没有@interface,只有@implementation,也可以开发一个类
- @property和@synthesize
- @property
- 用在@inteface中
- 用来自动生成setter和getter的声明
- 用@property int age;就可以代替下面的两行
- (int)age; // getter
- (void)setAge:(int)age; // setter
- @synthesize
- 用在@implementation中
- 用来自动生成setter和getter的实现
- 用@synthesize age = _age;就可以代替
- (int)age{
return _age;
}
- (void)setAge:(int)age{
_age = age;
}
- @synthesize的细节
- setter和getter实现中会访问成员变量_age
- 如果成员变量_age不存在,就会自动生成一个@private的成员变量_age
- setter和getter实现中会访问成员变量age
- 如果成员变量age不存在,就会自动生成一个@private的成员变量age
- 若手动实现了setter方法,编译器就只会自动生成getter方法
- 若手动实现了getter方法,编译器就只会自动生成setter方法
- 若同时手动实现了setter和getter方法,编译器就不会自动生成不存在的成员变量
- @property新特性
- 自从Xcode 4.x后,@property就独揽了@synthesize的功能。也就是说,@property可以同时生成setter和getter的声明和实现
- 默认情况下,setter和getter方法中的实现,会去访问下划线 _ 开头的成员变量
- id
- 简介
- 万能指针,能指向任何OC对象,相当于NSObject *
- id类型的定义
typedef struct objc_object {
Class isa;
} *id;
- 使用
// 注意:id后面不要加上*
id p = [Person new];
- 局限性
调用一个不存在的方法,编译器会马上报错
- 构造方法
- 对象创建原理
Person *p1 = [Person alloc];
Person *p1 = [p1 init];
合成一句后:
Person *p = [[Person alloc] init];
- init方法的重写
- 想在对象创建完毕后,成员变量马上就有一些默认的值
- init方法的重写过程
- (id)init
{
if (self = [super init])
{
_age = 10;
}
return self;
}
- 自定义构造方法
- (id)initWithAge:(int)age {
if (self = [super init]) {
_age = age;
}
return self;
}
- (id) initWithAge:(int)age andNo:(int)no;
- .h和.m文件的抽取
- 每个类分布在不同文件中
- 类的声明放在.h文件,类的实现放在.m文件
- 若想使用某个类,就包含某个类的.h声明文件
iOS 的 set.get.构造方法
标签:
原文地址:http://www.cnblogs.com/yumian/p/5123596.html