------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -----
第一讲 封装的概念及原理
本小节知识点:
1、【了解】为什么要进行封装
2、【了解】封装的原理
1、为什么要进行封装
不封装的缺点:
当一个类把自己的属性暴露给外部的时候,那么该类就是去对属性的管理权。
将数据隐藏起来,只能用此类的方法函数才可以访问或者设置数据,不可被外部
任意存储是面向对象设计本质。降低了数据被无用的可能性。
在OC中,使用@interface 和@implementation来处理类。
@interface就好像暴露在外面的时钟表面,向外界提供展示以及接口。
@implementation就好像隐藏在时钟内部的构造实现,把具体的实现封装了起来
2、封装的原理?
实例变量默认只能被当前类的对象方法访问。
1 // OC10-封装的概念及原理 2 3 #import <Foundation/Foundation.h> 4 5 @interface Gun : NSObject 6 { 7 @public 8 int _bulletCount; 10 } 11 -(void)shoot; 12 -(void)setBulletCount:(int)bulletCount; 13 @end 14 @implementation Gun 15 16 -(void)shoot{ 17 if(_bulletCount>0){ 18 19 NSLog(@"突突突,剩余子弹:%d",_bulletCount); 20 }else{ 23 NSLog(@"没子弹了,你还突突毛线呢"); 24 } 25 _bulletCount --; 27 } 28 -(void)setBulletCount:(int)bulletCount{ 29 30 //对这个子弹数进行封装 给它设置一个值 31 if (bulletCount>0) { 32 _bulletCount = bulletCount; 33 }else{ 34 _bulletCount = 0; 35 } 37 } 38 @end 39 int main(int argc, const char * argv[]) 40 { 42 @autoreleasepool { 44 Gun *gun = [Gun new]; 45 // gun->_bulletCount = -3; //这是不安全的 46 47 [gun setBulletCount:-3]; //封装后的 不管底层怎么实现的 49 [gun shoot]; 50 [gun shoot]; 51 [gun shoot]; 52 [gun shoot]; 54 } 55 return 0; 56 }
第二讲 封装的实现步骤
本小节知识点:
【掌握】封装的实现步骤
1、封装的步骤
定义设置实例变量(setter)和访问实例变量(getter)的方法。
1)setter方法(设置器)
在开发过程中,考虑到安全性要求,我们一般不再成员变量名前面使用@interface、@implementation等关键字修饰,而是使用Set方法来为对象提供成员变量的值。在set方法的内部也可以对一些不合理的赋值进行筛选过滤。
Set方法的作用:为外界提供一个设置成员变量值的方法。
命名规范:
(1)方法名必须以set开头
(2)Set后面跟上成员变量的名称,首字母大写
(3)返回值一定是void
(4)一定要接收一个参数,而且参数类型需要和成员变量的类型一致
(5)形参名不能和成员变量名一样(苹果官方推荐成员变量名前加_以示区分)
Set方法的好处:
(1)不让数据暴露在外,保证了数据的安全性
(2)对设置的数据进行过滤
2)getter方法(访问器)
Get方法的作用:为调用者返回对象内部的成员变量。
命名规范:
(1)一定有返回值,返回值的类型和成员变量的类型一致
(2)方法名和成员变量名一样
(3)不需要接收任何参数
1 // Person.h 2 #import <Foundation/Foundation.h> 3 4 typedef enum {kSexMan,kSexWomen,kSexYao}Sex; 5 @interface Person : NSObject 6 { 7 @public 8 //姓名 9 NSString *_name; 10 //年龄 11 int _age; 12 //性别 13 Sex _sex; 14 //身高 15 float _height; 16 } 17 //给每一个实例变量定义两个方法:设置变量的方法(set) 获取变量值的方法(get) 18 //set方法的书写规范: 19 //1、set方法一定是一个对象方法 20 //2、set方法一定不能有返回值 21 //3、set方法必须以set开头 22 //4、set之后跟的是 实例变量去掉下划线,并且首字母大写 23 //5、set方法一定有参数,而且参数的类型和实例变量的类型一致 24 //6、set方法的形参名 一般是 去掉下划线的实例变量名 25 //7、形参名不能和 实例变量名同名 26 //8、set方法实现中一定用行参给实例变量赋值 27 28 // set 和 get 方法对下面四个实例变量封装 29 //_name的set方法,以后对name设置值,一律使用此方法 30 -(void)setName:(NSString *)name; 31 -(void)setAge:(int)age; 32 -(void)setSex:(Sex)sex; 33 -(void)setHeight:(float)height; 34 35 //get方法书写规范 36 //1)get方法一定是一个对象方法 37 //2)get方法一定有返回值,返回值的类型和实例变量的类型要一致 38 //3)get方法的方法名 是去掉下划线的实例变量名 39 //4)get方法一定没有参数 40 //5)get方法的实现中,一定是返回值实例变量值 41 42 43 //NSString *_name 44 //以后获取name的值,都统一的使用name的get方法 45 -(NSString *)name; 46 //int _age; 47 -(int)age; 48 // Sex _sex; 49 -(Sex)sex; 50 // float _height; 51 -(float)height; 53 @end 56 // Person.m 57 #import "Person.h" 59 @implementation Person 61 //****** set 方法的实现 ****** 62 //_name的set方法,以后对_name设置值,一律使用此方法 63 -(void)setName:(NSString *)name{ 65 _name = name; 66 } 67 -(void)setAge:(int)age{ 68 _age = age; 69 } 70 -(void)setSex:(Sex)sex{ 71 _sex = sex; 73 } 74 -(void)setHeight:(float)height{ 75 76 _height = height; 77 } 78 79 //***** get 方法的实现 ******* 80 //以后获取name的值,都统一的使用name的get方法 81 -(NSString *)name{ 83 return _name; 84 } 85 //int _age; 86 -(int)age{ 88 return _age; 89 } 90 // Sex _sex; 91 -(Sex)sex{ 93 return _sex; 94 } 95 // float _height; 96 -(float)height{ 99 return _height; 100 } 101 102 @end 103 104 // OC11-封装的实现步骤 105 #import <Foundation/Foundation.h> 106 #import "Person.h" 107 int main(int argc, const char * argv[]) 108 { 109 110 @autoreleasepool { 111 112 Person *p = [Person new]; 113 114 //设置名称 115 //p->_name; 不这么写了 116 [p setName:@"萨达姆"]; 117 [p setAge:17]; 118 [p setHeight:1.83f]; 119 [p setSex:kSexMan]; 120 NSLog(@"%@,%d,%.2f,%d",[p name],[p age],[p height],[p sex]); 121 122 } 123 return 0; 124 }
二、封装应用:股票K线计算
练习:
设计一个k线类
最低价格(可读写)
最高价格(可读写)
平均价格(只读)
1 #import <Foundation/Foundation.h> 2 3 @interface KLine : NSObject 4 { 5 @public 6 //定义实例变量 7 float _minPrice; 8 float _maxPrice; 9 float _avgPrice; 10 } 11 //float _minPrice; 12 -(void)setMinPrice:(float)minPrice; 13 -(float)minPrice; 14 //float _maxPrice; 15 -(void)setMaxPrice:(float)maxPrice; 16 -(float)maxPrice; 17 //float _avgPrice; 18 -(float)avgPrice; 19 20 @end 21 22 #import "KLine.h" 23 24 @implementation KLine 25 //float _minPrice; 26 -(void)setMinPrice:(float)minPrice{ 27 _minPrice = minPrice; 28 _avgPrice=(_maxPrice+_minPrice)/2; 29 } 30 -(float)minPrice{ 31 32 return _minPrice; 33 } 34 //float _maxPrice; 35 -(void)setMaxPrice:(float)maxPrice{ 36 _maxPrice = maxPrice; 37 _avgPrice=(_maxPrice+_minPrice)/2; 38 } 39 -(float)maxPrice{ 40 return _maxPrice; 41 } 42 //float _avgPrice; 43 -(float)avgPrice{ 44 // _avgPrice = (_minPrice + _maxPrice)/2; 46 return _avgPrice; 47 } 49 @end 50 51 #import <Foundation/Foundation.h> 52 #import "KLine.h" 53 int main(int argc, const char * argv[]) 54 { 56 @autoreleasepool { 58 KLine *kline = [KLine new]; 59 [kline setMinPrice:30.2f]; 60 [kline setMaxPrice:50.4f]; 61 NSLog(@"avgPrice = %.2f",[kline avgPrice]); 62 63 } 64 return 0; 65 }
第三讲 组合模式
本小节知识点:
【理解】组合模式
一、 组合模式定义
把具有相同基类类型的对象组合到树形结构中,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
组合模式使得树形结构中的每个节点都具有相同的抽象接口,整个结构可作为一个统一的抽象结构使用,而不暴露其内部表示。每个节点的任何操作,可以通过抽象基类中定义的相同接口来进行。
二、何时使用组合模式
想把对象抽象成树形结构,具有“部分-整体”的层次关系。
想让客户端统一处理组合中的对象。
三、在ios中使用组合模式
在Cocoa Touch框架中,UIView对象被组合成一个树形结构,UIView对象可以包含其他的UIView对象。
这种组合方式便于统一用于事件处理和动作消息,例如处理渲染事件时,事件会在父视图中被处理,然后再传递给子视图,因为他们都是相同的类型,事件可以传递到树形结构的每一视图。
四、组合模式优缺点
优点:
客户端可以统一的使用组合对象或单个对象,而不组合结构不暴露其内部表示可以很容易在组合体内加入具有相同抽象类型的对象。客户端不必因为加入了新的对象而更改代码。
五、组合模式与装饰模式(Decorator)
Composite模式和Decorator模式虽然逻辑完全不同,但是从类图中可以看到它们有着相似的结构,Composite模式重在构造类,而Decorator模式重在不生成子类即可给对象添加职责。所以两种模式侧重点不一样,Decorator模式重在修饰,而Composite模式重在表示。
第四讲 依赖关系
【掌握】依赖关系
A对象作为B对象的局部变量或是方法形参的,B依赖与A,这时候我们称A与B之间存在一种依赖关系
B A
[p feedDog:dog];
面向对象设计中:
耦合度:当修改一个对象的时候,对另外一个对象的影响程度
低耦合:当修改一个对象的对其他对象影响比较小
高内聚:一个对象仅仅做自己相关的事情
面向对象设计原则: 单一职责原则
分析:
大胸美女打电话给土豪
找出这一实例中必须存在的对象
对象: 美女 手机
B A
[ girl callPhoneToTH:iphone];
girl 依赖 iphone
试着分析其关联关系:
1)女孩用手机给土豪打电话
callPhoneToTH:(Ipone *)iphone;
iphone 打电话
2)女孩用手机给土豪发短信
1 #import <Foundation/Foundation.h> 2 3 @interface IPhone : NSObject 4 { 5 NSString *_phoneNum; 8 } 9 //set方法 设置电话号码 10 -(void)setPhoneNum:(NSString *)phoneNum; 11 //get方法 有返回值 12 -(void)callPhone; 13 -(void)sendMsgPhone; 14 15 @end 16 17 #import "IPhone.h" 18 19 @implementation IPhone 20 //set方法 设置电话号码 21 -(void)setPhoneNum:(NSString *)phoneNum{ 22 23 _phoneNum = phoneNum; 24 } 25 //get方法 有返回值 26 -(void)callPhone{ 27 NSLog(@"给土豪A:%@打电话",_phoneNum); 28 29 } 30 -(void)sendMsgPhone{ 32 NSLog(@"给土豪A:%@发短信",_phoneNum); 35 } 36 @end 37 38 #import <Foundation/Foundation.h> 39 #import "IPhone.h" 40 @interface Girl : NSObject 41 { 44 } 45 //get方法 用什么手机 打电话 发短信 给谁 的返回值 46 -(void)callPhoneToTH:(IPhone *)iphone; 47 -(void)sendMsgPhoneToTH:(IPhone *)iphone; 48 @end 50 #import "Girl.h" 52 @implementation Girl 53 //get方法 打电话 发短信 给谁 的返回值 54 -(void)callPhoneToTH:(IPhone *)iphone{ 56 [iphone setPhoneNum:@"123456"]; 57 [iphone callPhone]; 58 } 59 -(void)sendMsgPhoneToTH:(IPhone *)iphone{ 61 [iphone setPhoneNum:@"123456"]; 62 [iphone sendMsgPhone]; 64 } 65 @end 66 67 #import <Foundation/Foundation.h> 68 #import "Girl.h" 69 int main(int argc, const char * argv[]) 70 { 72 @autoreleasepool { 74 //创建一个手机对象 75 IPhone *iphone7Plus = [IPhone new]; 76 //创建一个美女对象 77 Girl *girl = [Girl new]; 78 79 [girl callPhoneToTH:iphone7Plus]; 81 } 82 return 0; 83 }
第五讲 关联关系
【掌握】关联关系
1、关联关系
关联关系,HasA关系:当一个对象拥有另外一个对象的时候,
当B对象为A对象的成员变量的时候,B对象与A对象之间存在一种关联关系。
关联关系是面向对象中最常用一种关系
关联关系的耦合度更高于依赖关系
一对一: 一夫一妻制
一对多关系: 班级与学生 ,一个班级可以有多个学生
多对多关系: 学生与课程,一个学生可以学习多门课程,一门课程被多个学生选修
女孩开车 汽车 美女
女孩玩iPad 美女 iPad
分析出两个场景中的对象
关联关系:
1)美女A老公给美女买了一辆车(车是属于美女的)
2)美女B有一台iPad,正在听音乐(iPad是属于美女的)
思考&实现:
用关联关系实现 美女B 有一台iPad,并且用iPad听音乐的过程。
听歌的过程:
iPad听歌 ----player ------song---歌属性
Person类
属性:
姓名(name) iPad对象
方法:
设置姓名
设置iPad
听歌
iPad类
属性:
名称(name)播放器对象
方法:
安装播放器
设置名称
播放音乐
播放视频
玩游戏
播放器类:(player)
属性:
播放器名称
歌曲
方法:
设置播放器名称
设置歌曲
加载歌曲
播放歌曲
暂停歌曲
停止歌曲
歌曲类:(Song)
属性:
歌曲名
时长
歌手
方法:
设置歌手、歌曲名、时长的方法
歌曲播放的方法
1 #import <Foundation/Foundation.h> 2 /* 3 iPad类 4 属性: 5 名称(name) 6 方法: 7 8 设置名称 9 播放音乐 10 播放视频 11 玩游戏 12 */ 13 @interface IPad : NSObject 14 { 15 NSString *_name; 16 } 17 18 -(void)setName:(NSString *)name; 19 20 -(void)playMusic; 21 -(void)playMovie; 22 -(void)playGame; 23 @end 24 25 #import "IPad.h" 26 27 @implementation IPad 28 -(void)setName:(NSString *)name{ 29 _name = name; 30 } 31 32 -(void)playMusic{ 33 NSLog(@"正在用%@播放音乐",_name); 34 } 35 -(void)playMovie{ 36 NSLog(@"正在用%@播放电影",_name); 37 } 38 -(void)playGame{ 39 NSLog(@"正在用%@玩游戏",_name); 40 } 41 @end 42 43 44 #import <Foundation/Foundation.h> 45 #import "IPad.h" 46 /* 47 Person类 48 属性: 49 姓名(name) iPad对象 50 方法: 51 设置姓名 52 设置iPad 53 听歌 54 */ 55 @interface Person : NSObject 56 { 57 NSString *_name; 58 //人拥有一台IPad 59 IPad *_ipad; 60 61 } 62 //set方法 设置姓名 63 -(void)setName:(NSString *)name; 64 -(void)setIPad:(IPad *)ipad; 65 //get方法 听歌 66 -(void)listenMusic; 67 @end 68 69 #import "Person.h" 70 71 @implementation Person 72 //set方法 设置姓名 73 -(void)setName:(NSString *)name{ 74 _name = name; 75 } 76 -(void)setIPad:(IPad *)ipad{ 77 _ipad = ipad; 78 } 79 //get方法 听歌 80 -(void)listenMusic{ 81 [_ipad playMusic]; 82 } 83 @end 84 85 #import <Foundation/Foundation.h> 86 #import "Person.h" 87 int main(int argc, const char * argv[]) 88 { 89 90 @autoreleasepool { 91 92 //创建对象 93 IPad *ipad5 = [IPad new]; 94 95 [ipad5 setName:@"iPad5"]; 96 97 //人拥有iPad 98 Person *p = [Person new]; 99 [p setName:@"张三丰"]; 100 //把ipad给人 ,人用这个ipad 101 [p setIPad:ipad5]; 102 [p listenMusic]; 103 } 104 return 0; 105 }