理解封装
- 封装是面向对象的三大特征之一(继承 多态 封装) 它指的是 将对象的状态信息隐藏在对象的内部,不允许外部程序直接访问对象的内部信息 而只能通过该类的方法来实现 对内部信息的操作和访问
封装的目的
- 隐藏类的实现细节。
- ->让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,
限制对成员变量的不合理访问。 - ->可进行数据检查,从而有利于保证对象信息的完整性。
便于修改,提高代码的可维护性。
为了实现良好的封装,需要从以下两个方面考虑。 - ->将对象的成员变量和实现细节隐藏起来,不允许外部直接访问。
- ->把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作。
因此,封装实际上有两方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来。这两个方面都需要通过使用OC提供的访问控制符来实现
访问控制符
OC提供的访问控制符代表了四个访问控制等级
访问控制符介绍
- @private(当前类访问权限):如果类的成员变量使用@private 访问控制符来限
这个成员变量只能在当前类的内部访问。很显然,这个访问控制符用于彻底隐藏变量。在类的实现部分定义的成员变量相当于默认使用这种访问权限。 - @package(相同映像访问权限):如果类的成员变量使用@package 访问控制符来限制
-则这个成员变量可以在当前类以及当前类的同一个映像的任意地方访问。很显然,这个访问控制符用于部分隐藏成员变量。 - ** @protected(子类访问权限**:如果类的成员变量使用@ protected访问控制符来限制,
这个成员变量可以在当前类、当前类的子类的任意地方访问。很显然,这个访问控
符用于部分暴露成员变量。在类的接口部分定义的成员变量默认使用这种访问权限 - public(公共访问权限):这是一个最宽松的访问控制级别,如果类的成员变量使
@public 限制,那么这个成员变量可以在任意地方访问,不管是否处于同一映偰中
也不管是否具有父子继承关系。
表格
** 对于局部变量而言,其作用域就是他所在的方法,不可能被其他类昂问,因此不能使用访问控制符来修饰**
良好的封装实例
实现一个良好的封装
接口
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
//良好封装的接口
@interface FKperson : NSObject {
@private //限制成员变量只能被方法调用所赋值
NSString* _name;
int _height;
}
- (void) setName: (NSString*) name;
- (NSString*) getName;
- (void) setHeight: (int) height;
- (int) getHeight;
@end
NS_ASSUME_NONNULL_END
实现
#import "FKperson.h"
@implementation FKperson
//良好封装的实现
// 设置名字
- (void) setName: (NSString *) name {
if ([name length] > 6 || [name length] <2) {
NSLog(@"长度不符合请重新输入");
return;
} else {
_name = name;
}
}
// 获取名字
- (NSString *) getname {
return _name;
}
// 设置身高
- (void) setHeight: (int) height {
if (height > 200 || height < 0) {
NSLog(@"身高不符合");
} else {
_height = height;
}
}
// 获取身高
- (int) getHeight {
return _height;
}
@end
结果
解释思考
正正如上面程序中注释的,main0函数不可再直接修改 FKPerson 对象的name 和age 两个
成员变量,只能通过各自对应的setter 方法来设置这两个成员变量的值。当使用 setter 方法来
设置 name 和age 两个成员变量时,就允许程序员在 setter 方法中增加自己的控制逻辑,从而
保证 FKPerson 对象的name 和age 两个成员变量不会出现与实际不符的情形,
如有错误 评论区指正