? 实例变量可?度
可见度 | 特点 |
---|---|
public(公有的) | 实例变量可以在类的外部和内部操作 |
protected(受保护的,默认的) | 实例变量只能在本类和其?类内部操作 |
private(私有的) | 实例对象只能在本类内访问 |
所谓的内部,指的是相应类的@implementation和@end之间。
示例代码如下:
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
@public
NSString *_hobby; /**< 兴趣*/
@protected
NSString *_name; /**< 姓名*/
NSInteger _age; /**< 年龄*/
@private
NSString *_sex; /**< 性别*/
}
@end
@public实例变量的调用代码如下:
Person *person = [[Person alloc] init];
person->_hobby = @"打排球 看电影";
NSLog(@"兴趣: %@", person->_hobby);
@protected实例变量的调用代码截图如下:
@private实例变量的调用代码截图如下:
注意:
- 使[email protected]关键字,暴露了类内部的细节。
- 不符合面向对象语言的三大特性之?——封装。
因此,实际开发时尽量避免将实例变量声明为public。
? ?法
方法分类
Objective-C中的方法分两种:类方法和实例方法。
类方法:只能类使用,例如:+(id)alloc 注:类方法中不能使用实例变量。
实例方法:只能对象使用,例如: -(void)sayHi
?法声明
方法名
删除方法类型标识,返回类型,参数类型,参数名,空格。例如:
replaceObjectAtIndex:withObject:
类中不能出现同名方法,“ : ” 标识参数,不能省略,有冒号必须有参数。
赋值、取值方法(设置器、访问器或setter、getter)
- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setName:(NSString *)name
{
_name = name;
}
- (NSString *)name
{
return _name;
}
多参方法
- (instancetype)initWithName:(NSString *)name
sex:(NSString *)sex;
- (instancetype)initWithName:(NSString *)name
sex:(NSString *)sex
{
self = [super init];
if (self) {
_name = name;
_sex = sex;
}
return self;
}
方法使用
[person sayHi]
在Objective-C中没有”person调用sayHi“这种表述。在Objective-C中使用消息发送机制:[receiver message]。
正确表述:给person对象发送sayHi消息。
- person接收到消息,即方法sayHi;
- person找到sayHi方法,并执行。
三 setter getter
在OC里,为实例变量赋值的方法称作setter(设置器)。
读取实例变量值的?法称作getter(访问器)。
我们之前写的那些赋值、取值的方法都可以称作setter和getter。
setter、getter的书写格式
OC规定了setter和getter的书写格式。如果一个实例变量是int age;
或者int _age;
setter的书写格式如下:
- (void)setAge:(int)age;
即set + 忽略下划线的首字母大写的实例变量名。
getter的书写格式如下:
- (int)age;
即返回值类型与实例变量类型?致,?法名与实例变量名相同(忽略下划线)。
与实例变量的关系
无论setter还是getter内部操作的都是实例变量,每一个实例变量都需要一对setter和getter方法。
?定义初始化方法
-(id)init 这个初始化方法只能给实例变量设置默认值,不灵活。
-(id)initWithName: 自定义初始化方法,根据需求定义初始化方法。
示例代码如下:
- (instancetype)initWithName:(NSString *)name
sex:(NSString *)sex;
- (instancetype)initWithName:(NSString *)name
sex:(NSString *)sex
{
self = [super init];
if (self) {
_name = name;
_sex = sex;
}
return self;
}
#import
导入头文件,即:导入头文件中的内容到当前类。
#import “” 导入自定义类,#import <> 导入类库中的头文件。功能类似C语言中的#include,但是可以避免头?件被重复导入,但容易出现循环导入头文件问题。
@class
告诉编译器@class后的字符串作为类名使用,并未导入类的接口内容。有效避免嵌套循环导入。
示例:Student类, 实例变量: 姓名, 年龄, 老师;Teacher类, 实例变量: 姓名, 年龄, 学生。
@class使用 的示例代码如下:
#import <Foundation/Foundation.h>
@class Student; /* @class 标记Student是一个类, 不导入任何实例变量和方法 */
@interface Teacher : NSObject
{
@protected
NSString *_name;
NSInteger _age;
Student *_student; /* 学生 */
}
- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setAge:(NSInteger)age;
- (NSInteger)age;
- (void)setStudent:(Student *)student;
- (Student *)student;
- (id)initWithName:(NSString *)name
age:(NSInteger)age;
- (void)teacherInfo;
@end
#import "Teacher.h"
#import "Student.h" /* 在.m文件中导入头文件 */
@implementation Teacher
- (void)setName:(NSString *)name
{
_name = name;
}
- (NSString *)name
{
return _name;
}
- (void)setAge:(NSInteger)age
{
_age = age;
}
- (NSInteger)age
{
return _age;
}
- (void)setStudent:(Student *)student
{
_student = student;
}
- (Student *)student
{
return _student;
}
- (id)initWithName:(NSString *)name age:(NSInteger)age
{
_name = name;
_age = age;
return self;
}
- (void)teacherInfo
{
NSLog(@"name: %@ age: %ld myTeacher: %@", _name, _age, [_student name]);
}
@end
#import <Foundation/Foundation.h>
@class Teacher;
@interface Student : NSObject
{
@protected
NSString *_name;
NSInteger _age;
Teacher *_myTeacher;
}
- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setAge:(NSInteger)age;
- (NSInteger)age;
- (void)setMyTeacher:(Teacher *)myTeacher;
- (Teacher *)myTeacher;
- (void)studentInfo;
@end
#import "Student.h"
#import "Teacher.h"
@implementation Student
- (void)setName:(NSString *)name
{
_name = name;
}
- (NSString *)name
{
return _name;
}
- (void)setAge:(NSInteger)age
{
_age = age;
}
- (NSInteger)age
{
return _age;
}
- (void)setMyTeacher:(Teacher *)myTeacher
{
_myTeacher = myTeacher;
}
- (Teacher *)myTeacher
{
return _myTeacher;
}
- (void)studentInfo
{
NSLog(@"name: %@ age: %ld myTeacher: %@", _name, _age, [_myTeacher name]);
}
@end
#pragma mark 知识点5 @class使用
/* 作用: 避免循环导入 */
/* Student类, 实例变量: 姓名, 年龄, 老师
* Teacher类, 实例变量: 姓名, 年龄, 学生
*/
#if 1
/* 创建一个Teacher对象 */
Teacher *teaOne = [[Teacher alloc] init];
[teaOne setName:@"Tom"];
[teaOne setAge:40];
/* 创建一个Student对象 */
Student *stuOne = [[Student alloc] init];
[stuOne setName:@"Zhang San"];
[stuOne setAge:18];
[stuOne setMyTeacher:teaOne]; /* 先创建好teaOne对象 */
[stuOne studentInfo];
[teaOne setStudent:stuOne];
[teaOne teacherInfo];
/* 新Teacher对象 */
Teacher *teaTwo = [[Teacher alloc] initWithName:@"Steve" age:50];
[teaTwo setStudent:stuOne];
[teaTwo teacherInfo];
#endif
版权声明:本文为博主原创文章,未经博主允许不得转载。