面向对象编程(oop)
-
基本概念
- 对象:对象是消息的接收者
- 类:类是对象的蓝图和模板
- 消息:对象之间通信的手段
-
四大支柱
- 抽象:创建类的过程就是一个抽象的过程,需要进行数据抽象(找到和对象相关的属性)和行为抽象(找到和对象相关的方法)。
- 封装:隐藏一切可以隐藏的实现细节(累的成员变量、方法的具体实现),向外界(调用者)提供最简单的编程接口(方法)。
- 继承:从已经有的类创建新类的过程。提供继承信息的类称之为父类(超类、基类),得到继承信息的类称之为子类(派生类、衍生类)。
- 多态:同样的消息不同的执行方式(不看指针看对象,相同类型的指针指向不同子类型的对象执行相同的消息表现出不同的行为)。
-
三个步骤
- 定义类
- 创建对象
- 发消息
定义类:
类的声明部分:
@interface 类名 : 父类名 {
//成员变量(数据抽象)
}
// 属性(数据抽象)
// 初始化方法
// 方法(行为抽象)
@end
类的实现部分:
@implementation 类名
// 方法的实现
创建对象:
类名 *对象指针 = [[类名 alloc] 初始化方法];
发消息:
[对象指针 方法名];
返回可I型 变量名 = [对象指针 方法标签:参数];
[对象指针 方法标签1:参数1 标签2:参数2];
例子:
#import <Foundation/Foundation.h>
// Step 1. 定义类
// 数据抽象: 找到和类(对象)相关的属性(找名词)
// 行为抽象: 找到和类(对象)相关的方法(找动词)
// 类的声明部分
@interface Circle : NSObject {
// 数据抽象
@private double _radius;
}
// 类方法 +号 通过类名直接调用(给类发消息)
// 对象方法 -号 必须先创建对象才能调用(给对象发消息)
+ (instancetype) circleWithRadius:(double) radius;
// 初始化方法
//- (instancetype) initWithRadius:(double) radius;
// 行为抽象
- (double) perimeter;
- (double) area;
@end
// 类的实现部分
@implementation Circle
// 在类方法中self代表类
+ (instancetype)circleWithRadius:(double)radius {
return [[self alloc] initWithRadius:radius];
}
// 在对象方法中self代表对象
- (instancetype) initWithRadius:(double) radius {
if (self = [super init]) {
_radius = radius;
}
return self;
}
- (double) perimeter {
return 2 * M_PI * _radius;
}
- (double) area {
return M_PI * _radius * _radius;
}
@end
static const double WALL = 5.5;
static const double AISLE = 7.8;
int main() {
// 自动释放池(离开释放池申请的内存会做一次释放操作)
@autoreleasepool {
printf("请输入游泳池的半径: ");
double r;
scanf("%lf", &r);
// Step.2 创建对象
// 用中缀符语法给对象发消息
Circle *smallCircle = [Circle circleWithRadius:r];
Circle *bigCircle = [Circle circleWithRadius:r + 3];
// Step.3 给对象发消息求解问题
printf("The price of aisle is $%.2f\n",
([bigCircle area] - [smallCircle area]) * AISLE);
printf("The price of wall is $%.2f\n", [bigCircle perimeter] * WALL);
}
return 0;
}
系统常用类
-
字符串的使用(NSString/NSMutableString)
- 创建字符串
- +string
- +stringWithFormat:
- +stringWithUTF8String:
- +stringWithContentsOfFile:
- +stringWithContenstOfURL:
- 常用方法和属性
- length 获得字符串长度
- -characterAtIndex: 取指定位置的字符
- UTF8String 将字符串转成UTF编码的字符串
- -stringByAppendingString: 追加字符串
- -stringByAppendingFormat: 追加带样式的字符串
- -componentsSeparatedByString: 拆分字符串
- -substringFromIndex: 从指定位置取子串
- -substringToIndex: 取到指定位置的子串
- -substringWithRange: 取指定位置和长度的子串
- -containsString: 判断有没有包含另一个字符串
- -rangeOfString: 查找另一个字符串出现的位置
- -stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement: 用指定字符串替换某些字符串
- -compare: 比较两个字符串
- -isEqualToString: 判断两个字符串内容是否相同
- -hasPrefix: 判断字符串是否以指定的字符串开头
- -hasSuffix: 判断字符串是否以指定的字符串结尾
- -uppercaseString: 获得大写字符串
- -lowercaseString: 获得小写字符串
- -capitalizedString: 获得首字母大写字符串
- NSMutableString 特有的:
- -appendFormat: 追加字符串
- -appendString: 追加带格式的字符串。
- -insertString: atIndex: 在指定位置插入字符串
- -replaceCharactersInRange: withString: 用指定的字符串替换指定范围的字符串
- 创建字符串
-
数组(NSArray/NSMutableArray)
// 数组里面只能放对象指针,不能放基本数据类型
// 频繁的修改数组元素建议使用NSMutableArray- containsObject: 判断数组中有没有指定对象
- count 数组元素的个数
- firstObject 取数组中第一个元素
- lastObject 取数组中最后一个元素
- indexOfObject: 在数组中查找指定的对象返回位置(下标)或者(NSNotFound)
- sortedArrayUsingDescriptor: 用指定的排序描述符创建一个元素有序的数组
NSMutableArray 特有的方法:
- addObject: 向数组中添加元素
- addObjectsFromArray: 批量添加元素
- insertObject:atIndex: 在指定位置插入元素
- removeAllObjects:删除所有元素
- removeLastObject:删除最后一个元素
- removeObject:删除指定的元素
- removeObjectAtIndex:删除指定位置的元素
- sortUsingDescriptor:用指定的描述对数组进行排序
-
字典(NSDictionary/NSMutableDictionary)
- count 键值对组合的数量
- allkeys 获得所有的键
- allValues 获得所有的值
- -objectForKey: 查找指定键的值
NSMutableDictionary的方法 - -serObject:forKey: 添加新的键值对组合
- -removeObjectForObject: 根据指定的键删除键值对组合
- -removeAllObjects: 删除所有的键值对组合
类别(Category)
给已有的类打一个补丁包,增强它的功能。
一个类方法比属性更重要。
#import <Foundation/Foundation.h>
@interface NSString (Util)
- (instancetype) reverse;
- (instancetype) encodeWithKey:(NSInteger) key;
- (instancetype) decodeWithKey:(NSInteger) key;
@end
#import "NSString+Util.h"
@implementation NSString (Util)
- (instancetype) reverse {
NSMutableString *mStr = [NSMutableString string];
for (NSInteger i = self.length - 1; i >= 0; i--){
unichar ch = [self characterAtIndex:i];
[mStr appendFormat:@"%C", ch];
}
return [mStr copy];
}
- (instancetype) encodeWithKey:(NSInteger) key {
NSMutableString *mStr = [NSMutableString string];
for(int i = 0; i < self.length; i++){
unichar ch = [self characterAtIndex:i];
ch = ch ^ key;
[mStr appendFormat:@"%C", ch];
}
return [mStr copy];
}
- (instancetype) decodeWithKey:(NSInteger) key {
return [self encodeWithKey:key];
}
@end
#import <Foundation/Foundation.h>
#import "NSString+Util.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *str = @"我恨你中国";
NSLog(@"%@", [str reverse]);
NSString *encodedStr = [str encodeWithKey:100];
NSLog(@"%@", encodedStr);
NSLog(@"%@", [encodedStr decodeWithKey:100]);
}
return 0;
}
![屏幕快照 2016-03-23 20.52.31.png](https://img.haomeiwen.com/i1787713/b6132b4f2c60a787.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
提示:在Category定义的方法命名时,最好加上命名前缀,例如命名类的前缀时ZP,那么Category中的方法应加上zp_前缀,这样做主要是为了让调用者能够区分是苹果原生的方法还是Category新加的方法。
属性(Property)
//一个顶三个
@property (属性修饰符) 类型 变量名;
在默认的情况下,属性会自动合成成员变量以及setter(修改器)、getter(访问器)方法,如果不愿意使用自动合成,也可以在类的实现部分(.m)通过@synthesize指令指定属性如何合成。
说明:如果需要向外部暴露对象的某个属性就是用@property,这样可以通过点语法来操作这个属性;如果不想暴露对象的某个属性(将数据保护起来)就应该直接定义成员变量。
网友评论