封装
一、
什么是错误
一般情况下,错误是指源代码不符合语法规范,然后编译报错
后果: 程序无法编译什么是Bug?
程序可以编译、链接、执行,但是程序执行的结果不是我们预想的。
解决: 通过调试寻找发生Bug的原因.异常
程序可以编译、链接、执行,当程序在执行的时候,处于某种特定的条件下,程序就会终止。
后果: 程序立即终止运行-
如何处理异常
1). 目的: 为了让程序在执行的时候如果发生了异常而不崩溃
2). 语法@try{ }@catch(NSException *ex){ }
将有可能发生异常的代码放在@try中.
当@try中的代码在执行的时候,如果发生了异常,不会奔溃,而是立即跳到@catch中执行代码。
当@catch的代码执行完毕后,结束@try...@catch往下执行.
如果没有发生异常, 则跳过@catch往下执行.3). 当@try中的代码在执行的时候发生了异常,@try块发生异常后面的代码不会被执行.
@catch中的代码只有在@try的代码发生异常的时候才会被执行,所以@catch中我们一般情况下写处理异常的代码.
@catch的参数NSException *ex通过%@打印出ex指向对象的值,可以拿到发生异常的原因
-
@try...@catch后面还可以跟1个@finally块
``` @try{ }@catch(NSException *ex){ }@finally{ } ```
@try...@catch并不是万能的, 并不是所有的运行时错误都可以处理的。
类方法
0). 在一个Target中无法访问另外一个Target中的方法.
1). OC中的方法分为两种
a. 对象方法/实例方法
想要调用对象方法就必须要先创建对象,然后调用
b. 类方法
类方法的调用不依赖于对象. 如果要调用类方法,不需要创建对象
2). 类方法声明
a. 对象方法的声明:
对象方法的声明 - 号
- (返回值)方法名;
- (void)sayHi;
b. 类方法的声明:
类方法声明使用 + 号
+ (返回值类型)方法名;
3). 调用
a. 对象方法: 先创建对象再通过对象名来调用
b. 类方法: 不需要创建对象, 直接使用类名来调用
[类名 类方法名];
4). 分析类方法和对象方法
a. 类方法的特点
a). 节约空间
b). 提高效率
5). 在类方法中不能直接访问属性
因为属性只有在对象创建的时候才会创建在对象之中,而类方法在执行的时候有可能还没有对象。
虽然不能直接访问属性,但是我们可以在类方法中创建一个对象访问这个对象
a. 属性是在对象创建的时候跟随着对象一起创建在对象之中
b. 类第1次在访问时回做类加载在类方法中不能使用self来调用其他对象方法
[self 方法名];//调用当前类型的方法在对象方法当中可以调用类方法
[类名 方法名];什么时候可以将方法定义为类方法
如果方法不需要直接访问属性,也不需要直接调用其他的对象方法,可以定义为类方法-
关于类方法的规范.
1). 如果我们写一个类,要求为这个类提供一个与类名同名的方法,这个方法创建 创建一个纯净的对象返回. 苹果和第三方都遵守这个规范- (Person *)person;
2). 如果希望创建的对象的属性的值由调用者指定,那么这个类方法带参数.
类名WithXXX:... - (Person *)personWithName:(NSString *)name andAge:(int)age;
- (Person *)person;
二、
NSString 是1个数据类型,用来保存OC字符串的
其实NSString是Foundation框架中的1个类,作用存储OC字符串.所以OC中的字符串本质上是用NSString对象来存储的.
完整的标准的创建NSString对象的方式
NSString *str = [NSString new];
NSString *str1 = [NSString string];
这种方式创建的字符串是空字符串 @""
但是NSString是最常用的1个对象, 所以OC使用了1种更为简单的方式来创建对象,直接使用@来表示1个OC字符串.
NSString *str = @"jack";
@"jack" 本质上是一个NSString对象,str是这个对象的地址.-
NSString最常用的类方法
1). + (instancetype)stringWithUTF8String:(const char *)nullTerminatedCString
instancetype作为返回值,代表返回当前这个类的对象char *str0 = "rost"; NSString *str1 = [NSString stringWithUTF8String:str0];
2). + (instancetype)stringWithFormat:(NSString *)format, ...使用频率非常高
作用: 拼接1个字符串对象,使用变量或者其他数据拼接成OC字符串int age = 19; NSString *name = @"小明"; [NSString stringWithFormat: @"大家好,我叫%@, 我今年%d岁.",name,age]
-
最长用的对象方法
1). length方法, 返回值NSUInteger,计算字符串长度NSString *str = @"itcast"; NSUInteger len = [str length];
2). 得到字符串中指定下标的字符
- (unichar)characterAtIndex:(NSUInteger)index;
返回值是unichar, 其实就是unsigned short,占据两个字节.
如果要输出unichar变两个的值使用%C
NSString *str = @"itcast"; unichar ch = [str characterAtIndex:2];
3). 判断两个字符串是否相同
a. 判断两个字符串内容是否相同, 不要使用==判断
b. 判断相等的方式
- (BOOL)isEqualToString:(NSString *)aString;
判断两个字符串是否相等应该使用上面的方法来判断.NSString *str1 = @"jack"; NSString *str2 = @"jack"; [str1 isEqualToString: str2];
4). 判断两个字符串大小
- (NSComparisonResult)compare:(NSString *)string;
NSComparisonResult是个枚举, 完全可以使用int来接收返回值.NSString *str1 = @"jack"; NSString *str2 = @"jack"; [str1 compare: str2];
- (unichar)characterAtIndex:(NSUInteger)index;
-
匿名对象
1). 之前创建对象的做法:
Person *p1 = [Person new];
让1个指针指向1个对象2). 匿名对象
没有名字的对象, 如果我们创建一个对象,没有用1个指针存储这个对象的地址,也就是没有任何指针指向这个对象,那么这个对象就叫做匿名对象.3). 如何使用1个匿名对象
[Person new]->_name = @"jack";
[[Person new] sayHi];4). 注意点
a. 匿名对象只能使用一次
b. 每次创建匿名对象都是不同的对象5). 使用情况
a. 某个对象只会被使用一次
b. 如果方法的参数是一次对象, 并且这个对象调用者不会使用
三、 面向对象的三大特征: 封装、继承、多态
封装:
a. 函数就是封装的体现
b. 类就是更高级别的封装
好处: ->屏蔽内部的实现, 外界不需要知道内部是如何实现的
->方便操作
继承:
多态:
-
setter封装
1). 将属性的@public去掉, 一旦写上@public就可以直接访问对象的这个属性.- 为类提供1个方法,专门为这个属性赋值,这个方法我们叫做setter。
a. 这个方法一定是1个对象方法
b. 没有返回值
c. 这个方法的名称必须以set开头, 跟上去掉下划线首字母大写的属性名.
d. 这个方法一定是有参数的, 参数的类型和属性的类型一致, 参数的名称和属性的名称一致(去掉下划线)
e. 在方法的实现中,检测传入的数据是否符合要求
// 声明 @interface Person : NSObject{ int _age; } - (void) setAge(int age); @end // 实现 @implementation Person - (void) setAge(int age){ _age = age; } @end // 调用 Person *p = [Person new]; [p setAge:10];
- 为类提供1个方法,专门为这个属性赋值,这个方法我们叫做setter。
-
getter封装
1). 用来取出属性的值
a. 这个方法一定是一个对象方法
b. 这个方法返回值类型和属性的类型一致
c. 这个方法的名称直接属性的名称(去掉下划线)
d. 这个方法没有参数
e. 外界想要获取这个值,直接调用方法即可.// 声明 @interface Person : NSObject{ int _age; } - (void) setAge(int age); - (int)age(); @end // 实现 @implementation Person - (void) setAge(int age){ // 可以做验证 _age = age; } - (int)age(){ return _age; } @end // 调用 Person *p = [Person new]; [p setAge:10]; [p age];
-
注意
- 属性的@public一定要去掉
- 判断参数的值是否符合逻辑
- getter/setter方法名极度不规范
什么时候需要封装getter/setter
1). 只要属性需要被外界访问就要回这个属性封装setter和getter, 就算赋值或者取值的时候没有任何逻辑验证
2). 如果属性只在内部访问, 不需要封装getter/setter只读只写封装
只读封装: 为属性封装的时候,只提供getter属性
只写封装: 为属性封装的时候,只提供setter属性对象之间的关系
1). 组合关系: 一个类是由其他几个类组合而成的
2). 依赖关系: 一个对象的方法的参数是另外一个类
a. 耦合度: 当一个类修改之后另一个类无法使用,叫高耦合
b. 低耦合:当一个类修改之后另一个类正常使用,叫高耦合
c. 高内聚: 一个对象仅仅只做自己相关的事情
d. 单一职责原则: 一个类只做自己的事情
3). 关联关系: 两个类之间语义级别的一种强依赖关系, 拥有关系
4). 继承关系: