黑马程序员--Objective-C语言基础知识--特有语法
来源:互联网 发布:手机专业相机软件 编辑:程序博客网 时间:2024/04/30 04:04
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
分类(Category)
一、
在不改变原来类模型的前提下,给类扩充方法,除了可以利用继承特性设计一个子类外,还可以通过设置分类来完成。
分类的格式:
分类的声明:@interface 类名(分类名称)......@end分类的实现:@implementation 类名(分类名称)......@end
示例1:
#import <Foundation/Foundation.h>@interface Person : NSObject@property int age;@property NSString *name;@property double height;- (void)run;- (void)jump;@end@implementation Person- (void)run{ NSLog(@"跑起来了");}- (void)jump{ NSLog(@"跳起来了");}@end@interface Person (Liyi)//声明Person的分类,取名为LiYi- (void)shoot;//在分类中给Person扩充一个方法shoot@end@implementation Person(LiYi)- (void)shoot//实现这个扩充的方法{ NSLog(@"LiYi shoot");}@endint main(){ Person *per = [Person new];//创建一个Person对象 [per shoot];//per调用分类中扩充的方法shoot return 0;}
示例1的运行结果是:
2015-07-19 15:26:03.792 a.out[1028:189268] LiYi shoot
示例1展示了分类的用法。
二、
分类的好处:
1. 一个庞大的类可以分模块开发;
2. 一个庞大的类可以由多个人来编写,有利于团队合作。
三、
注意点:
1. Category可以访问原始类的实例变量,但不能添加变量,只能添加方法;
2. Category可以实现原始类的方法,但是不推荐这么做,因为它是直接替换掉原来的方法,这样做的后果是再也不能访问原来的方法;
3. 多个Category中如果实现了相同的方法,只有最后一个参与编译的分类中的实现方法才会有效。
协议(@protocol)
一、
协议可用来声明一大堆方法(不能声明成员变量),只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明,只要父类遵守了某个协议,就相当于子类也遵守了。
协议的格式:
协议的编写:@protocol 协议名称方法声明列表@end某个类遵守协议:@interface 类名 : 父类<协议名称>@end
一个类可以遵守多个协议。
二、
协议中有2个关键字可以控制方法是否要实现(默认是@required),大多数情况下,用于程序员之间的交流。
@required:方法前面添加这个关键字意味着这个方法必须要实现,如果不实现编译器会发出警告。
@optional:方法前面添加这个关键字表示这个方法不一定要实现。
三、
协议也可以遵守协议,一个协议可以遵守其他多个协议,多个协议之间用逗号隔开。一个协议遵守了其他协议就相当于拥有了其他协议中的方法声明。
书写格式:
@protocol 协议名称<协议1, 协议2>@end
我们知道NSObject是一个基类,最基本的类,任何其他类最终都要继承它,其实还有一个基协议叫NSObject,它是最基本的协议,通常每个新协议都要遵守NSObject协议。
四、
我们在定义变量时可以限制这个变量保存的对象遵守某个协议,如果没有遵守编译器将会发出警告。通常我们用万能指针(id)定义变量来做协议遵守的限制。
书写格式:
类名<协议名称> *变量名;id<MyProtocol> obj;
协议可以定义在单独的.h文件中,也可以定义在某个类中。如果这个协议只用在某个类中,应该把协议定义在该类中。如果这个协议用在多个类中就应该定义在单独文件中。
示例2:
#import <Foundation/Foundation.h>@protocol Grab<NSObject>@optional- (void)drive;@required- (void)potholing;@end
示例2在Gab.h文件中编写了一个协议,声明了两个方法一个不要求遵守者必须实现,一个要求遵守者必须实现。
示例3:
#import <Foundation/Foundation.h>#import "Grab.h"@interface Person : NSObject<Grab>@property(nonatomic, strong)NSString *name;@property(nonatomic, assign)int age;@property(nonatomic, assign)int height;- (void)jump;- (void)run;@end
示例3在Person.h文件中声明了一个遵守Grab协议的Person类。
示例4:
#import "Person.h"@implementation Person- (void)jump{ NSLog(@"跳跃");}- (void)run{ NSLog(@"奔跑");}- (void)potholing{ NSLog(@"开挖掘机挖坑");}@end
示例5在Person.m文件中实现了Person所遵守的协议中的potholing方法。
示例6:
#import <Foundation/Foundation.h>#import "Person.h"int main(){ id<Grab> obj = [Person new]; [obj potholing]; return 0;}
示例6在main.m文件中应用了遵守Grab这个协议的Person类,我们设定了一个万能指针限制其所指的对象必须遵守Grab协议,Person类的对象是符合要求的。
示例6的运行结果是: 2015-07-19 16:37:08.251 a.out[1148:296322] 开挖掘机挖坑
五、
代理设计模式:
有时候有些事情不想自己做,就想找个人帮忙,这个人就是我们的代理对象。代理设计首先得拥有某个代理对象属性,然后要保证代理人遵守协议,最后利用代理人实现协议内容。
我们用代理设计模式模拟这么一个场景:一个人想挖个坑但是自己不想挖,就像找一个能开挖掘机的司机帮他干这个活,这个司机就是他的代理人,协议就是这个人必须得开挖掘机挖。
示例7:
@protocol Grab<NSObject>@required- (void)drivingExcavator;@end
写一份协议,找得人得遵守这个协议:开挖掘机。
示例8:
#import <Foundation/Foundation.h>#import "Grab.h"@interface Person : NSObject@property(nonatomic, strong)id<Grab> obj;//找的代理人限制其必须遵守我定的协议- (void)potholing;@end#import "Person.h"@implementation Person- (void)potholing{ [_obj drivingExcavator];}@end
这个人找的司机必须得是遵守协议的,找到司机后就可以帮他挖坑了。
示例9:
@interface Driver : NSObject@end@implementation Driver- (void)drivingExcavator{ NSLog(@"驾驶挖掘机去挖坑");}@end
司机实现了协议中的方法,亦即他开挖掘机挖坑。
示例10:
#import <Foundation/Foundation.h>#import "Person.h"#import "driver.h"int main(){ Person *person = [Person new]; Driver *driver = [Driver new]; person.obj = driver; [person potholing]; return 0;}
示例10模拟了我们设定的场景:想挖坑的人找了个开挖掘机的人帮他把坑挖了。
运行结果是:
2015-07-19 17:47:12.172 a.out[1467:384592] 驾驶挖掘机去挖坑
类的本质
一、
其实类也是一个对象,是Class类型的对象,简称“类对象”。类就是以类对象的形式存储在内存中的。
二、
+load方法:在程序启动的时候会加载所有的类和分类,并自动调用所有类和分类的+load方法,先加载父类再加载子类也就是先调用父类的+load方法再调用子类的+load方法。此外先加载原始类再加载子类。不管程序运行过程中有没有用到这个类,都会调用+load加载。
+initialize方法:在第一次使用某个类时(比如创建对象等),就会调用一次+initialize方法,一个类只会调用一次+initialize方法,先调用父类的再调用子类的。
获取类对象的方法:
方法1:Class c = [Person class];方法2:Person *p = [Person new];Class c = [p class];
类对象调用类方法。
输出对象
我们要打印输出某个类通常使用NSLog函数和“%@”格式转换符,在输出对象时会调用- description方法,这个方法继承自基类,它的返回值是一个字符串,输出的就是这个方法默认返回的字符串。
示例11:
#import <Foundation/Foundation.h>@interface Student : NSObject@property(nonatomic, assign)int num;@property(nonatomic, assign)double height;@end@implementation Student@endint main(){ Student *stu = [Student new];//创建对象stu NSLog(@"%@", stu);//输出对象stu return 0;}
示例11的运行结果是:2015-07-19 18:16:07.759 a.out[1512:402681] <Student: 0x7fbf3b412940>
默认情况下输出的是对象的类名以及它在内存中的存储地址。
我们可以重写- description方法来输出我们自己想要的效果。
示例12:
#import <Foundation/Foundation.h>@interface Student : NSObject@property(nonatomic, assign)int num;@property(nonatomic, assign)double height;@end@implementation Student- (NSString *)description{ return [NSString stringWithFormat:@"这个学生的学号是%d身高是%.2f", _num, _height];/*重写description方法输出对象的具体属性*/}@endint main(){ Student *stu = [Student new]; stu.num = 9; stu.height = 1.82; NSLog(@"%@", stu); return 0;}
示例12的运行结果是:这个学生的学号是9身高是1.82
代码块(Block)
Block封装了一段代码,可以在任何时候执行。Block可以作为函数参数或者函数返回值,而其本身又可以带参数或返回值。苹果官方建议尽量多用Block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多。
Block的定义方式:
int (^MySum)(int, int) = ^(int a, int b){ return a + b;};//不同于函数代码块定义结束一定要加“;”号,不加编译器会报错
以上我们定义了一个叫MySum得block对象,它带有两个int型参数,返回int型值。
block可以访问局部变量,但是不能修改局部变量。
示例13:
#import <Foundation/Foundation.h>int main(){ int a = 5, b = 9; int (^Sum)(int, int) = ^(int x, int y){ return x + y; }; int sum = Sum(a, b); NSLog(@"sum = %d", sum); return 0;}
示例13展示了代码块的简单应用,运行结果是:
sum = 14
- 黑马程序员--Objective-C语言基础知识--特有语法
- 黑马程序员——Objective-C语言知识点总结之OC特有语法
- 黑马程序员--Objective-C——OC特有语法一
- 黑马程序员--Objective-C——OC特有语法二
- 【黑马程序员】iOS学习之路——Objective-C之特有语法
- 黑马程序员--Objective-C语言基础知识--面向对象
- 黑马程序员--Objective-C语言基础知识--三大特性
- 黑马程序员_OC特有语法
- 黑马程序员---OC--特有语法
- 黑马程序员 OC语言 - 4 OC特有语法
- 黑马程序员-OC语言基础:OC特有语法
- 黑马程序员——Objective-C语言知识整理——Objective-C语言基础知识总结
- 黑马程序员---C语言基础知识
- 黑马程序员 之 Objective-C 语法整理
- 黑马程序员 之 Objective-C 点语法
- 黑马程序员Objective-C笔记:点语法
- 【黑马程序员】---Objective-C核心语法总结
- 黑马程序员----objective-C 基础语法篇
- 19-linux中一些命令
- 无线互联01
- 2015年07月04日第四天笔记
- hdu 1879 继续畅通工程
- 安静的转换有多安静?
- 黑马程序员--Objective-C语言基础知识--特有语法
- leetCode(43):Product of Array Except Self
- 2015年07月06日第五天笔记
- Two big challenges in machine learning
- PHP数组的使用方法小结
- hdu 3068 最长回文 (Manacher模版)
- 如何升级openssl到最新版本 ubuntu
- Java的反射机制
- c# 鼠标中的各种形状