面向对象的三大特性:封装、继承和多态

  封装目的就是将数据隐藏起来,外界只能通过这个类的方法(接口)才能访问或者设置里面的数据,不可以在外部直接修改或者访问里面的数据,通常使用方法来达到封装一个类的目的,最终使这个类达到高内聚低耦合的目的.

  耦合说的是一个软件结构宏各个模块之间的相互关联相互紧密的程度,模块之间的联系越精密,其耦合性也就越强,模块间耦合的高低取决于模块之间接口的复杂性,调用信息的方式及传递的信息.

  内聚说的是单个模块内各个元素之间彼此结合的紧密程度,所谓高内聚就是一个软件模块是由相关性很强的代码组成,只负责一项任务.

一 Setter 和 getter方法的实现

  设置器Setter的作用:为外界提供一个设置成员变量值的方法,说到底就是一种可以在外界调用,并为成员变量赋值的方法.

  命名规范:

  1.  一定是对象方法,以减号" - "开头

  2. 返回值类型一定是 void

  3. 方法名一定是: set+实例变量名去掉下划线"_",且首字母大写,比如:给_age 写setter方法, setAge:

  4. 一定要接收一个参数,不然如何进行赋值呢?参数类型一定要和实例变量的类型一致,参数名就是实例变量名去掉下划线"_" 如: - (void)setAge:(NSInteger)age;

  Setter方法的好处(1)不让数据暴露在外,保证了数据的安全性;(2)对设置的数据进行过滤

  Setter方法声明:

// _age的setter方法

-   (void)setAge:(NSInteger)age;

// _gender 的setter方法

   - (NSInteger)gender;

  Setter方法的实现:

// _age的setter方法
- (void)setAge:(NSInteger)age {
    // 如果检测到给年龄赋了值赋值,那么直接返回
    ) {
        return;
    }
    // 将外界传入的内容,赋值给实例变量
    _age = age;

}

// _gender的setter方法
- (void)setGender:(NSString *)gender {
    _gender = gender;
}

  访问器 getter方法

  getter方法的作用:为调用者返回对象内部的实例变量

  命名规范:

  1. 一定是对象方法,以"-"开头

  2. 一定有返回值且返回值类型和实例变量的类型一定要一致

  3. 方法名: 不加get, 直接用 实例变量名去掉下划线书写  如: _age的getter方法是: age

  4. 此方法不需要接收任何参数

  getter方法的声明:

// _age 的getter方法
- (NSInteger)age;

// _gender的getter方法
- (NSString *)gender;

  getter方法的实现:

// _age 的getter方法
- (NSInteger)age {
    // 将实例变量返回就可以了
    return _age;
}

// _gender的getter方法
- (NSString *)gender {
    // 返回实例变量
    return _gender;
}

  注意:在实际的开发过程中,如果内部的实例变量,比如学号之类的数据只允许外界读取而不允许修改,那么只需要提供get方法而不提供set方法.因此不一定setter和getter方法都会提供.

  完整示例:

创建一个Person类,对其实例变量实现setter和getter方法

Person.h

@interface Person : NSObject
// 实例变量
{
    @public  //实例变量可见度的修饰符,下面将会讲到,暂时不用管
    NSString *_name; //姓名
      @protected
    NSInteger _age; //年龄
    @private
    NSString *_gender; //性别
}

// _age的setter和getter方法
- (void)setAge:(NSInteger)age;
- (NSInteger)age;
// _gender的setter和getter方法
- (void)setGender:(NSString *)gender;
- (NSString *)gender;

@end

Person.m

@implementation Person
// _age的setter getter方法
- (void)setAge:(NSInteger)age {
    ) {
        return;
    }
    // 将外界传入的内容,赋值给实例变量
    _age = age;
}

- (NSInteger)age {
    // 将实例变量返回就可以了
    return _age;
}

// _gender的setter getter方法

- (void)setGender:(NSString *)gender {
    _gender = gender;

}

- (NSString *)gender {
    // 返回实例变量
    return _gender;
}
@end

二 实例变量的可见度

  1.实例变量的可见度修饰符主要有3种:

  可见度修饰符       类的内部             子类

   @public         可以直接访问      可以直接访问

  @protected    可以直接访问      可以直接访问

   @private       可以直接访问      不可以直接访问

  系统默认的实例变量可见度修饰符:@protected

  实例变量的可见度的修饰符的作用范围,从其所在的那一行起到大括号结束,或者碰到下一个可见度修饰符结束;

@public

@public 修饰的变量虽然可以在类的外部直接访问,看起来很方便,但是破坏了类的封装特性,所以不建议使用@public

@public 公共的,公开的,被它修饰的实例变量,不止能在类的内部直接访问,也能在类的外部直接访问方法;

内部访问方式: 直接使用实例变量名 例如: _age

外部访问方式: 对象->实例变量名 例如: p->_age

Person *p = [[Person alloc] init];

// 调用_name的setter方法
p->_name = @"张三"; //外部访问,使用->
// 调用_name的getter方法
NSLog(@"%@", p->_name);

@protected

@protected  受保护的,不允许在类的外部直接访问,但是可以在类的内部和子类的内部直接访问,是系统默认的实例变量可见度.

  // 内部访问: 直接使用实例变量名

  // 外部访问: 赋值需要通过设置器setter进行访问,取值通过访问器getter进行访问

    //调用_age的setter方法:
    [p setAge:-];

    //调用_age的getter方法
    NSInteger age = [p age]; 

@private

@private 私有的,外部不能直接访问,内部可以直接访问,在子类中不可以直接访问,但是可以通过方法进行访问

内部访问: 通过接使用实例变量名

类的外部: 通过设置器和访问器访问

    // 调用_gender的setter方法
    [p setGender:@"男"];

    // 调用_gender的getter方法
    NSLog(@"%@", [p gender]);

练习: 定义一个Student类型,实例变量使用三种可见度,修饰其三个实例变量.使用protect, private修饰的变量写setter和getter方法

Student.h文件中声明:

@interface Student : NSObject
{
    @public
    NSString *_name;
    @protected
    NSInteger _number;
    @private
    CGFloat _score;
}

// _number 的setter getter方法
- (void)setNumber:(NSInteger)number;
- (NSInteger)number;

// _score 的setter getter方法
- (void)setScore:(CGFloat)score;
- (CGFloat)score;

@end 

Student.m文件中实现:

@implementation Student

 // _number 的setter方法
- (void)setNumber:(NSInteger)number {
    _number = number;
}

// _number 的getter方法
- (NSInteger)number {
    return _number;
}

// _score 的setter方法
- (void)setScore:(CGFloat)score {
    _score = score;
}

//_score 的getter方法
- (CGFloat)score {
    return _score;
}
@end

回到main中调用各实例变量的setter 和getter方法:

 // 创建一个Student对象stu:
    Student *stu = [[Student alloc] init];
   // 被@protected修饰的实例变量 _number
    // 调用_number的setter方法
  [stu setNumber:];
    // 调用_number的getter方法
    NSLog(@"%ld", [stu number]);

  // 被@private修饰的 _score
    // 调用 _score 的setter方法
    [stu setScore:80.0];
    // _score 的getter方法
    NSLog(@"%.2f", [stu score]); 

点语法

如果一个实例变量对它实现了setter和getter语方法,就可以使用点语法了.因此,使用点语法的前提是对该实例变量使用了setter和getter方法

点语法只是setter和getter方法的一种快捷调用

    stu.number = ;       // 就相当于 [stu setNumber:12315];

    NSLog(@"%ld", stu.number); // 相当于 [stu number];

点语法使用总结: 如果后面有赋值运算符(=),此时此时相当于这个实例变量的setter方法;后面没有赋值运算符,此时相当于调用这个实例变量的getter方法

Objective-C学习篇02—封装的更多相关文章

  1. iOS-H5学习篇-02

    H5-自学笔记-2016年09月06日 一:各种标签的练习 Html和CSS的关系 学习web前端开发基础技术需要掌握:HTML.CSS.JavaScript语言. 1.1.1. HTML是网页内容的 ...

  2. 深入js的面向对象学习篇(封装是一门技术和艺术)——温故知新(二)

    下面全面介绍封装和信息隐藏. 通过将一个方法或属性声明为私用的,可以让对象的实现细节对其它对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束.在代码有许多人参与设计的情况下, ...

  3. pythonchallenge之C++学习篇-02

    第二关任然是一个字符处理的关卡 查看网页源码发现有一大串字符需要处理,这么多的字符如果放在源代码里就很不好了 所以要用到C++对文件的操作,用到的头文件是fstream 这里参照了这个博文 对文件处理 ...

  4. objective C 学习之02

    1. 函数 -(void) HelloWorld:(BOOL)ishelloworld{ //干点啥 } 前面带有减号(-) 的方法为实例方法,必须使用类的实例才可以调用的.对应的有+号, 代表是类的 ...

  5. 【从零开始自制CPU之学习篇02】555定时器

    555定时器是一种集成电路芯片,常被用于定时器.脉冲产生器和震荡电路.在CPU制作中作为pc(程序计数器)的主要组成部分.以下是我购买的NE555实拍图: NE555的针脚示意图: 555定时器各针脚 ...

  6. c++学习笔记之封装篇(上)

    title: c++学习笔记之封装篇(上) date: 2017-03-12 18:59:01 tags: [c++,c,封装,类] categories: [学习,程序员,c/c++] --- 一. ...

  7. Springboot学习06-Spring AOP封装接口自定义校验

    Springboot学习06-Spring AOP封装接口自定义校验 关键字 BindingResult.Spring AOP.自定义注解.自定义异常处理.ConstraintValidator 前言 ...

  8. J2EE学习篇之--Struts1详解

    今天来看一下Struts1的相关知识,其实Struts现在是出名的,每个Web开发者都会知道的,也是现在比较流行的框架,下面就来看一下我们为什么要用Struts框架呢? 摘要 1.建立在mvc这种好的 ...

  9. OC学习篇之---总结和学习目录

    今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生 ...

随机推荐

  1. 获取Delphi所有类的类信息

    Delphi遍历进程中所有Class的TypeInfo,即便是在implementation中的class或者其他 class的private的子class. 一般普通EXE中的TypeInfo存放在 ...

  2. HDU 4612 Warm up(手动扩栈,求树上哪两个点的距离最远)

    题目大意: 给你一个无向图,问加一条边之后最少还剩下几座桥. (注意重边处理)   分析:其实当我们把边双连通分量给求出来之后我们就能将连通块求出来,这样我们就可以重新构图.重新构造出来的图肯定是一颗 ...

  3. 数学(快速数论变换):SDOI2015 序列统计

    [题目描述] 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S. 小C用这个生成器生成了许多这样的数列.但是小C有 ...

  4. 【模拟赛】BYVoid魔兽世界模拟赛 解题报告

    题目名称(点击进入相关题解) 血色先锋军 灵魂分流药剂 地铁重组 埃雷萨拉斯寻宝 源文件名(.c/.cpp/.pas) scarlet soultap subway eldrethalas 输入文件名 ...

  5. lightoj 1407 2-sat

    这题的英语either...or....很蛋疼: m中,1:x与y至少一个出席:2:x出席,y随便,x不出席,y也不出席----这有个坑,可以推出y出席x也一定出席(这个关系必须要连上):3x与y至少 ...

  6. RHEL 6.4 安装svn和apache

    1.安装软件包(RHEL已经按默认设置安装完成) 需要安装的.rpm软件包: postgresql-libs perl-URI subversion mod_dav_svn 2.创建svn文件夹和版本 ...

  7. 一个IT男的创业感言

    2014年的一月 我和高中的一个同学開始人生的第一次创业.就写点第一次创业的经验吧! 创业的最初 须要心中大概有个规划 这个规划可能是非常粗糙的 但大的方向一定要有.详细就是你进入的行业 行业已经存在 ...

  8. UVALIVE 4819 最大流

    题意:有N场比赛,每场比赛需要一定数量的题目数,现在有M个题目,每个题目只能提供给特定的几场比赛,并且一次只能在一场比赛中出现. 问最多可以举办多少场比赛. 思路:因为N = 15 , 所以直接二进制 ...

  9. MySQL的字符编码体系(二)——传输数据编码

    MySQL的字符编码体系能够分成两部分:一部分是关于数据库server本身存储数据表时怎样管理字符数据的编码:还有一部分是关于client与数据库server数据传输怎样编码.上一篇MySQL的字符编 ...

  10. [转] doxygen使用总结

    doxygen [功能] 为许多种语言编写的程序生成文档的工具. [举例] *生成一个模板配置文件,模板文件中有详细的注释: $doxgen -g test 这样,会生成一个test文件,1500多行 ...