------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1、封装
程序进行了封装可以使代码变得轻便,也提高了运行效率。
不封装的缺点:把类暴露在外面,失去了对属性的管理权。
@interface就好像暴露在外面的时钟表面,向外界提供接口及战士,@implementation就好比隐藏在时钟内部的构造实现,把具体的实现封装起来。
封装的原理:实例变量默认只能被当前类的对象方法访问。
用户只是关心外部的操作过程,内部如何的实现并不关心。用户只需要给设置子弹数gun setBulletCount : -3,至于底部如何实现的对他们没有关系。
底部封装的是方法的声明和实现,用户看不到的:
//枪类声明
@interface Gun :NSObject
{
@public
NSString *_size;//枪的型号
int _bulletCount;//枪的子弹数
}
//行为,士兵开火
-(void)shoot;
-(void)setBulletCount:(int)bulletCount;
@end
// 枪类实现
@implementation Gun
- (void)shoot{
//每射击一次子弹个数减一
if (_bulletCount > 0){
_bulletCount--;
NSLog(@"\n%@ 正在射击,剩余子弹:%d",_size, _bulletCount);
}
else{
NSLog(@"\n%@ 没有子弹数");
}
}
//子弹数的实现
-(void)setBulletCount:(int)bulletCount{
if (_bulletCount > 0){
_bulletCount = bulletCount;
}
else{
_bulletCount = 0;
}
}
@end
能展示给用户看到的或能设置操作的部分:
int main(int argc, const char *argv[]){
@autoreleasepool{
//创建枪对象
Gun *gun = [Gun new];
/* gun->bulletCount = -3;*///子弹个数成员变量赋值
//传入子弹数
[gun setBulletCount : -3];
//调用发射方法
[gun shoot];
[gun shoot];
}
return 0;
}
2、封装 的步骤
定义设置实例变量(set)和访问实例变量(get)
A set方法(设置器)
开发过程中,考虑到安全的要求,不使用之前在变量名前面使用@public等关键字,而是使用set方法,设置成员变量值,还可以对一些不合理的赋值进行筛选。
作用:为外界提供一个设置成员变量值的方法
命名规范:
- 方法名必须以set开头,一定是一个对象方法
- set后面跟上成员变量的名称,首字母大写,去掉下划线的。_name可以用set方法为SetName
- 返回值一定是void,不能有返回值
- 一定要接收一个参数,而且参数类型和成员变量要一致
- 形参名不能和成员变量名一样(一般成员变量名加_)
- 实现中,一定要用形参给实例变量赋值
- 形参名一般是去掉下划线的实例变量名
在@interface中声明NNString *_name;以下进行设置和获取变量值。
声明:-(void)setName:(NNString *)name;//以后对name设置值,用此方法
实现:-(void)setName:(NNString *)name{
_name=name;//_name成员变量值,name形参名
}
B get方法(访问器)
作用:为调用者返回对象内部的成员变量
命名规范:
- 一定有返回值,返回值的类型和成员变量的类型一致
- 方法名和成员变量名一样,是去掉下划线的实例变量名
- 不需要接收任何参数
- 一定是一个对象方法
- get方法实现一定是返回值是实例变量名
形式:声明:-(NSString *)name;//NSString *返回类型,name方法名
注意:以后获取name的值,统一使用name的get方法
实现:-(NSString *)name{
return _name;
}
3、对象间的关系
A 组合模式
相同基类类型的对象组合到树形结构中,成为“部分-整体"的层次结构,对单个对象和组合对象的使用有一致性。也就是有同一个接口的对象可以进行组合。
优点:
- 客户端可以统一使用组合对象或单个对象,而不组合结构不暴露其内部表示
- 可以很容易在组合体内加入具有相同抽象类型的对象,客户端不用因为加入了新对象而更改代码
B 依赖关系(重点)
A对象作为B对象的局部变量或方法形参,此时B依赖于A。
[person foodDog:dog],此时dog是形参,是A,person是B。
耦合度:修改一个对象时候,对另外一个对象的影响程度。
低耦合:修改一个对象时对其他对象影响比较小
高内聚:一个对象仅仅做自己相关的事情
面向对象设计原则:单一职责原则
实例:女孩给土豪打电话,分析主要对象为女孩,手机
1.对手机类,女孩类声明
//手机类声明
@interface Iphone :NSObject
{
NSString *_phoneNum;
}
-(void)setPhoneNum:(NSString *)phoneNum;
//打电话
-(void)callPhone;
@end
//女孩类声明
@interface Girl :NSObject
//打电话
- (void)callPhoneToHao : (Iphone *) ipone;
@end
2.对手机类,女孩类实现
//手机类实现
@implementation Iphone
- (void)setPhoneNum:(NSString *)phoneNum{
_phoneNum = phoneNum;
}
- (void)callPhone{
NSLog(@"给土豪打电话:%@",_phoneNum);
}
@end
//女孩类实现
@implementation Girl
- (void)callPhoneToHao : (Iphone *)ipone{
[ipone setPhoneNum : @"123456"];
[ipone callPhone];//手机拨号
}
@end
3.主函数调用
int main(int argc, const char *argv[]){
@autoreleasepool{
Iphone *ipone7 = [Iphone new];
Girl *girl = [Girl new];
//女孩打电话,依赖于手机
[girl callPhoneToHao : ipone7];
return 0;
}
C 关联关系(HasA关系)
当一个对象拥有另外一个对象的时候,B对象为A对象的成员变量时,即A包含B,A与B是关联关系。
关联关系是耦合度高于依赖关系。
实例:人拿ipad听音乐
1.人和ipad分别声明
//人类声明
@interface Person :NSObject
{
NSString *_PersonName;
//有一个Ipad
Ipad *_ipad;
}
//设置姓名和ipad
-(void)setPersonName : (NSString *)personName;
-(void)setIpad : (Ipad *)ipad;
//听音乐
-(void)listenMusic;
@end
//ipad类声明
@interface Ipad :NSObject
{
NSString *_ipadName;
}
//设置ipad名称
-(void)setIpadName : (NSString *)ipadName;
//听音乐
-(void)playMusic;
@end
2.人和ipad分别实现
//人类实现
@implementation Person
- (void)setPersonName : (NSString *)personName{
_personName = personName;
}
-(void)setIpad : (Ipad *)ipad{
_ipad = ipad;
}
-(void)listenMusic{
[_ipad playMusic];
}
@end
//ipad类实现
@implementation Ipad
- (void)setIpadName : (NSString *)ipadName{
_ipadName = ipadName;
}
-(void)playMusic{
NSLog(@"正在用%@播放音乐", _ipadName);
}
@end
3.测试调用主函数
int main(int argc, const char *argv[]){
@autoreleasepool{
//ipad赋值
IpadName *ipad5 = [IpadName new];
[ipad5 setIpadName:@"setIpadName"];
//人有ipad
Person *person = [Person new];
[person setPersonName:@"张三丰"];
//把ipad5给人
[person setIpad : @"ipad5"];
[person listenMusic];
return 0;
}
4、方法的重载
在一个类中可以定义多个同名的方法,但要求每个方法具有不同参数的类型或参数的个数。
这是在c++,java中有的,在OC中是没有。
在OC中的重载应该是值参数个数不同,但是返回类型后面的名字相同;或者是参数个数相同,但是其标签不同。
例如:-(void) test:(int) num;
-(void) test:(float) num1;//错误,与第一个方法重名test:
-(void) test:(int) a andY:(int) y;
-(void) test:(int) a andY:(float) y;错误,与第一个方法重名test:andY:
-(void) test:(int) a :(float) y;//正确,名字不同
5、static关键字
A 使用static不允许修饰实例变量,egstatic int _num;错误的,实例变量不能声明为静态,没有初始化的静态变量存在BSS段,已经初始化了的存在数据区
B不能使用static修饰方法
C静态的全局变量只能当前文件中使用
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------