一、延展Extension是个什么东西:它是个特殊的分类
1.是1个特殊的分类,所以延展也是类的一部分
2.延展的特殊之处:
1)延展这个特殊的分类,没有名字,以前讲过的分类,是不要取个名字啊,记住,延展这个特殊的分类没有名字
2)延展只有声明,没有实现,它的实现是和本类共享1个实现
3.延展的语法:
@interface 本类名 ()
@end
()这里面什么都不要写,就有1个小括号就可以了,这就是延展的声明
有没有@implementation呢,没有,记住,延展只有声明,没有实现。那它的实现在什么地方呢,我们刚刚说过,和本类共享1个实现
二、举个例子:
1.先有1个本类:Person类,如下:
#import <Foundation/Foundation.h>
@interface Person : NSObject @property(nonatomic,strong)NSString *name; @property(nonatomic,assign)int age;
#import “Person.h”
@implementation Person
(void)sayHi {
NSLog(@“大家好!”); } @end
2.再给它来1个延展:点右键,New File-Objective- C File,选择Extension,给这个延展取个名字,test,我们说过延展是1个分类对不对,那你要延展谁呢,延展Person对不对。
3.这时候,你发现与我们的分类不同的地方在于,它只有一个.h文件,有.m文件吗,没有。而且,刚才给延展取的名字test,是延展的文件名,并不是延展的名字,因为我们说过,延展是没有名字的。你看它声明的@interface Person (),它里面有名字吗,没有。首先这是个分类,因为这个分类没有名字,所以它叫延展。
4.只有1个.h文件,文件名称:本类名+延展的文件名.h,这个文件当中,只有延展的声明
@interface Person ()
@end
5.这个延展,它的作用,仍然是作为类的一部分,也就是这时候,我可以把Person的成员,写在本类里面,也可以把Person的成员,写在延展里面。你不管写在什么地方,都是同一个Person类,例如,在延展中写个方法吧,写个- (void)run;方法,再来一个方法,写个- (void)sleep;方法
#import “Person.h”
@interface Person ()
- (void)run;
- (void)sleep;
这是@interface,是不写声明啊,那么问题来了,这个实现应该写在哪里。我们刚刚说过,延展只有声明没有实现,是不是,它的实现,那我现在要实现run方法,要实现sleep方法,这个方法应该在哪儿实现呢,对,在本类的.m文件中实现。我们刚刚说过,延展和本类共享1个实现
在Person.m文件中
#import “Person.h”
@implementation Person
- (void)sayHi
{
NSLog(@“大家好。”);
}
@end
写在这里,那你看,有提示吗,没有。为什么没有,你都没有引进来,怎么会有提示呢。
#import “Person+test.h”
就有提示了
- (void)run
{
NSLog(@“我跑。。。”);
}
- (void)sleep
{
NSLog(@“呵呵,睡觉。”);
}
我们在main.m文件里试一下啊,我们试一下
#import <Foundation/Foundation.h>
#import “Person+test.h”
int main()
{
Person *p1 = [Person new];
[p1 sayHi];
[p1 run];
[p1 sleep];
return 0;
}
输出:大家好!
我跑。。。
呵呵,睡觉。
三、总结一下延展的基本使用
1.延展的本质是1个分类,作为本类的1部分,只不过是1个特殊的分类。特殊在哪个地方呢,第一,没有名字,第二,没有单独的实现
2.延展只有声明,没有单独的实现,和本类共享1个实现
3.延展和分类的区别
1)分类当中是不是只能加方法啊。延展当中,可以加属性,例如:
Person+test.h文件中:
#import “Person.h”
@interface Person ()
{
float _height;
}
- (void)run;
- (void)sleep;
@end
2)延展当中,还可以写@property,例如:
Person+test.h文件中:
#import “Person.h”
@interface Person ()
{
float _height;
}
@property(nonatomic,assign)float weight;
- (void)run;
- (void)sleep;
@end
3)那写完@property后,会自动的生成下划线私有属性吗,会的,在main.m文件中,打个断点试一下,果然有_weight属性了。说明这个延展中的@property会不会生成虾滑下私有属性啊,会。
4)那写完@property后,会自动生成getter、setter声明和实现吗,也会,声明是声明在延展里面,实现是实现在本类的.m文件里面。
5)延展和分类的区别:
a 分类有名字,而延展没有名字,是1个匿名的分类
b 每1个分类都有单独的声明和实现,而延展只有声明,没有单独的实现,和本类共享1个实现
c 分类当中只能新增方法,而延展当中,任意的成员都可以写
d 分类当中可以写@property ,但是只会生成getter、setter的声明,其他两件事情是不会做的,哪两件事情,生成下划线私有属性,和生成getter、setter的实现,而延展当中,写@property,3件事情都会做,会自动生成下划线私有属性,也会生成getter、setter的声明和实现,实现是生成在本类的实现当中
在main.m文件中试一下,能不能生成getter、setter的声明和实现
#import <Foundation/Foundation.h>
#import “Person+test.h”
int main(int argc, const char * argv[])
{
Person *p1 = [Person new];
[p1 sayHi];
[p1 run];
[p1 sleep];
p1.weight = 45.5f;
NSLog(@“p1.weight = %f”,p1.weight);
return 0;
}
答案是,可以。