Objective-C学习篇02—封装
面向对象的三大特性:封装、继承和多态
封装目的就是将数据隐藏起来,外界只能通过这个类的方法(接口)才能访问或者设置里面的数据,不可以在外部直接修改或者访问里面的数据,通常使用方法来达到封装一个类的目的,最终使这个类达到高内聚低耦合的目的.
耦合说的是一个软件结构宏各个模块之间的相互关联相互紧密的程度,模块之间的联系越精密,其耦合性也就越强,模块间耦合的高低取决于模块之间接口的复杂性,调用信息的方式及传递的信息.
内聚说的是单个模块内各个元素之间彼此结合的紧密程度,所谓高内聚就是一个软件模块是由相关性很强的代码组成,只负责一项任务.
一 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—封装的更多相关文章
- iOS-H5学习篇-02
H5-自学笔记-2016年09月06日 一:各种标签的练习 Html和CSS的关系 学习web前端开发基础技术需要掌握:HTML.CSS.JavaScript语言. 1.1.1. HTML是网页内容的 ...
- 深入js的面向对象学习篇(封装是一门技术和艺术)——温故知新(二)
下面全面介绍封装和信息隐藏. 通过将一个方法或属性声明为私用的,可以让对象的实现细节对其它对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束.在代码有许多人参与设计的情况下, ...
- pythonchallenge之C++学习篇-02
第二关任然是一个字符处理的关卡 查看网页源码发现有一大串字符需要处理,这么多的字符如果放在源代码里就很不好了 所以要用到C++对文件的操作,用到的头文件是fstream 这里参照了这个博文 对文件处理 ...
- objective C 学习之02
1. 函数 -(void) HelloWorld:(BOOL)ishelloworld{ //干点啥 } 前面带有减号(-) 的方法为实例方法,必须使用类的实例才可以调用的.对应的有+号, 代表是类的 ...
- 【从零开始自制CPU之学习篇02】555定时器
555定时器是一种集成电路芯片,常被用于定时器.脉冲产生器和震荡电路.在CPU制作中作为pc(程序计数器)的主要组成部分.以下是我购买的NE555实拍图: NE555的针脚示意图: 555定时器各针脚 ...
- c++学习笔记之封装篇(上)
title: c++学习笔记之封装篇(上) date: 2017-03-12 18:59:01 tags: [c++,c,封装,类] categories: [学习,程序员,c/c++] --- 一. ...
- Springboot学习06-Spring AOP封装接口自定义校验
Springboot学习06-Spring AOP封装接口自定义校验 关键字 BindingResult.Spring AOP.自定义注解.自定义异常处理.ConstraintValidator 前言 ...
- J2EE学习篇之--Struts1详解
今天来看一下Struts1的相关知识,其实Struts现在是出名的,每个Web开发者都会知道的,也是现在比较流行的框架,下面就来看一下我们为什么要用Struts框架呢? 摘要 1.建立在mvc这种好的 ...
- OC学习篇之---总结和学习目录
今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生 ...
随机推荐
- 根据body的内容 查找h2标签的@class="subtitle"的值
<pre name="code" class="html"><body class="api jquery listing" ...
- find the mincost route(floyd变形 无向图最小环)
Time Limit: 1000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- POJ-Common Substrings(后缀数组-长度不小于 k 的公共子串的个数)
题意: 长度不小于 k 的公共子串的个数 分析: 基本思路是计算 A 的所有后缀和 B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于 k 的部分全部加起来. 先将两个字符串连起来,中间 ...
- 扩展KMP模板
注意:需要用特殊符号隔开 1 struct ExKmp{ void Init(){ memset(f,,sizeof(f)); memset(r,,sizeof(r)); } void Get_Fai ...
- 搜索(DLX):HDU 3663 Power Stations
Power Stations Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- Linux下动态库的使用
1.生成动态库: gcc -fPIC -shared -o libdemo.so demo.c 考虑程式库major的升级会破坏兼容性:而minior的升级则可能不会,一般建议用以下方式来生成动态库. ...
- How To Create a New User and Grant Permissions in MySQL
How to Create a New User Let’s start by making a new user within the MySQL shell: CREATE USER 'newus ...
- python多线程机制
Python中的线程从一开始就是操作系统的原生线程.而Python虚拟机也同样使用一个全局解释器锁(Global Interpreter Lock,GIL)来互斥线程多Python虚拟机的使用. GI ...
- SSL证书的分类(按功能)
SSL证书的分类(按功能) 一.域名型证书 DV SSL DV SSL 证书是 Domain Validation SSL Certificate 英文全称的简写,翻译成中文是域名型 SSL证书 或 ...
- Eclipse 在线汉化
1. 打开Eclipse , 进入菜单中 Help-->Install new Software.. 2. 到Eclipse 官网找到语言包地址,http://www.eclipse.org/ ...