您的位置:首页 > 移动开发 > Objective-C

Objective-C学习笔记_实例变量可⻅度及方法

2015-08-02 14:53 369 查看

⼀ 实例变量可⻅度

[thead]
[/thead]
可见度特点
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实例变量的调用代码截图如下:



注意:

使⽤@public关键字,暴露了类内部的细节。

不符合面向对象语言的三大特性之⼀——封装。

因此,实际开发时尽量避免将实例变量声明为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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: