【延展Extension的使用场景 Objective-C语言】

一、延展到底是用来干嘛的,延展的应用场景:

1.分类是干嘛的,分类是将1个臃肿的类,拆分成多个模块,方便后期管理。

2.延展可以做这个事情吗,不可以,为什么,延展没有单独的实现,它怎么把1个类分多个模块呢,分不了啊,分不了。

3.分类的第二个作用,是不是为1个先有的类加方法啊,做扩展啊

4.延展可不可以,也不可以,为什么,因为延展没有单独的实现啊,你如果加方法,你最多只能加个方法的声明,实现的话,你还放在哪儿去,还放在本类的实现里面去,而绝大多数场景下,本类你是访问不了的。你看不见的,你怎么去修改人家的类呢。

5.是吧,所以,到底这个延展,该怎么用!什么时候用!以及如何用!

1)大家思考1个问题,比如,我这里有1个类:Student类,现在我有1个要求,让你为这个Student类写1个私有的@property,什么叫私有的@property啊,就是它生成的getter、setter方法,只能在本类的内部访问,不能在外部访问。

2)要为类写1个私有的@property:生成的getter、setter方法,只能在类的内部访问,不能在外部访问

之前是怎么写的,是不这么写的啊:
Student.h文件:
#import <Foundation/Foundation.h>

@interface Student : NSObject
@property(nonatomic,assign)int age;
@end

但你这么写的话,生成的getter、setter能不能在外部访问呢,能!现在的要求是,生成的getter、setter不能在外部访问,只能在类的内部访问,这个叫私有的@property,怎么做

@property是不做3件事情啊,1.生成下划线的真私有属性,2.生成getter、setter方法的声明,3.生成getter、setter方法的实现啊

我只要让它第2件事情不要做,就可以了,它只要值生成实现,不生成声明,这不就私有的了吗!外界就不能访问了吧

3)其实,可以这么想:只让@property生成私有属性,生成getter、setter的实现,不要声明,那大家思考一下,@property能这么做吗,能不让它生成getter、setter的声明吗,不行!因为@property天生就做这3件事情。

4)那我们可不可以把@property写在Student.m文件里,绝对不可以。报“Unexpected @ in program”错误,@property只能写在@interface里面

5)第1种最简单粗暴的方式,你就手写嘛。

在Student.m文件中:

#import “Student.h”

@implementation Student
{
int _age;
}

  • (void)setAge:(int)age
    {
    _age = age;
    }
  • (int)age
    {
    return _age;
    }
    @end

我这么写,是不相当于写了1个私有的@property啊,因为这个时候,没有getter、setter的声明,只有实现吧,这时候只能在类内部访问,不能在外部访问吧,但是你这么写的话,@property不是又白学了嘛。又回到原始社会了,是不是。那这个时候,我就是要来个私有的@property,怎么办,就用延展。

6.这个延展怎么用,例如:在Student.m文件中,这个延展我写在哪儿呢,记住,写在这个地方,我直接把这个延展,写在Student类的实现里面,在Student.m文件中:

#import “Student.h”

@interface Student ()

@end

@implementation Student

@end

我在这里面,写个@property

#import “Student.h”

@interface Student ()

@property(nonatomic,assign)int age;

@end

@implementation Student

@end

第一个问题,Student类里面,有没有age这个@property,有,会不会生成私有属性,会,会不会生成getter、setter方法的声明,会,声明在什么地方的,延展里面的,会不会有实现,实现在本类的实现里面的。

这个时候,我能不能在main.m文件里访问这个age属性,不行,能不能用setAge方法,不行.

所以这个时候,你想写个私有的@property的时候,你就可以用这种方式,写在延展里面

7.延展100%的情况下不会独占1个文件,你不会看到有谁写个延展,是独占1个文件的,不会,都是将延展直接写在本类的实现文件中,大家思考一下,我吧延展写在本类的实现文件中,我在延展里写的成员,就相当于是这个类的私有成员

这个时候,写在延展中的成员,就相当于是这个类的私有成员,只能在本类的实现当中访问,外部不能访问

我们试一下,例如:我们说延展里是不可以写属性,是不还可以写方法,在Student.m文件中:

#import “Student.h”

@interface Student ()
{
NSString *_name;
}
@property(nonatomic,assign)int age;

– (void)study;
@end
@implementation Student

@end

实现在哪儿实现,是不在本类的实现中实现

#import “Student.h”

@interface Student ()
{
NSString *_name;
}
@property(nonatomic,assign)int age;

– (void)study;
@end
@implementation Student
– (void)study
{
NSLog(@“我们在努力的学习。。。”);
}
@end

在main.m文件中,引入"Student.h"文件,创建1个Student对象:

#import <Foundation/Foundation.h>
#import “Student.h”
int main()
{
Student *s1 = [Student new];
}

首先,你会发现,第一个啊,s1.age是没有的,第二个,s1->isa,s1指向的,只有isa指针,第三个,有没有study方法呢,也调不了study方法。也就是说,延展当中的成员,你就没法调用。

但是,定义在@interface,本类的声明当中的成员,能不能调呢,在Student.h文件中:

#import <Foundation/Foundation.h>
@interface Student:NSObject
{
int _xxx;
}
– (void)hehe;

在Student.m文件中实现一下:

#import “Student.h”

@interface Student ()
{
NSString *_name;
}
@property(nonatomic,assign)int age;

  • (void)study;
    @end

@implementation Student

  • (void)study
    {
    NSLog(@“努力的学习。。。”);
    }
  • (void)hehe
    {
    NSLog(@“呵呵。。。”);
    }
    @end

在main.m文件中试一下:

#import <Foundation/Foundation.h>
#import “Student.h”
int main()
{
Student *s1 = [Student new];
s1->//s1指向的有没有_xxx属性,有
[s1 hehe];//hehe方法能不能调用,可以
}

8.为什么不能访问延展当中的成员呢,原因很简单,因为你这儿main.m文件中只引入了"Student.h"文件啊,你就只能访问"Student.h"文件中定义的成员啊,那我这里main.m文件中可不可以引入"Student.m"文件,报错,我们之前在多文件开发时讲过,你只能引入.h文件,不能引入.m文件,如果你引入.m文件的话,就会造成循环引用的错误。因为只能引入.h文件,所以我就把延展写在.m文件里,所以,延展中的成员就是这个类的私有成员

9.什么时候使用延展:当你想为这个类定义私有成员的时候,就可以使用延展。

10.怎么用:将延展定义在这个类的实现文件当中,这个类要有哪些私有成员,你就通通把这些私有成员写在延展中就好了。

二、我想为这个类定义1个私有属性,其实私有属性,也可以定义在.m文件的@implementation中:

@implementation Student
{
int _age;
}
@end

但记住,从此以后,不要这么写了,以后如果说你要为一个类定义一个真私有属性,不要写在@implementation中,而是怎么做,而是写个延展,把这个属性写在延展里面,有人问,为什么,第一个是因为这是国际化的规范,第二个是因为,@implementation是用来干嘛的,是不专门来写方法实现的啊,所以你别把属性往里面写了

1.如果想要为类写1个真私有属性,虽然我们可以定义在@implementation之中,但是,不要这么写,因为这样很不规范,那要怎么写呢

写1个延展,将这个私有属性定义在延展当中

2.那我想写个私有方法呢,根据我们之前讲的,私有方法怎么定义就可以了,是不直接写实现就可以了吧:

在Student.m文件中

#import “Student.h”

@interface Student ()
{
NSString *_name;
}
@property(nonatomic,assign)int age;

  • (void)study;
    @end

@implementation Student

  • (void)study
    {
    NSLog(@“努力的学习。。。”);
    }
  • (void)hehe
    {
    NSLog(@“呵呵。。。”);
    }
  • (void)play
    {
    NSLog(@“玩。。。”);
    }
    @end

直接这么写,是不play方法就是私有方法了,不能在外部调用,只能在类的内部调用了

记住,这么写其实是不好的

如果说你要写1个私有方法,应该怎么写

先写1个延展,把这个方法的声明,声明在这个延展当中

然后在这个类的.m文件中,写这个方法的实现

这个方法同样是私有方法,不能在外部调用,只能在类的内部调用

为什么要这样写呢,大家思考一下,我这个类里面,是不有可能会有很多方法,是不有可能会有很多私有方法,那么别人在看我这个类的时候,他可能想知道一下,你这个类里面到底有哪些私有方法啊,对了,他只要看看延展当中的方法就可以了,声明在延展中的方法,就是私有方法,声明在@interface本类中的方法,就不是私有方法,就可以在外部调用

你想想,如果像我们之前那样,通通不写声明,只写实现,那么这个时候,对于代码的阅读来讲的话,他看到这个方法的实现以后,能不能在外部调用呢,他还要去@interface里面找一下,有没有这个方法的声明

3.如果要为类写1个私有方法,建议将声明写在延展当中,实现写在本类的实现当中,提高代码的阅读性

如果想要为类写1个私有的@property,就直接写在延展当中,就可以了

4.所以说,延展天生就是来私有化类的成员的

如果类的成员只希望在类的内部访问,那么就将其定义在延展当中

如果类的成员,允许被外界访问,那么就定义在本类的@interface当中

5.例如,有一个Girl类,Girl是不有一个name属性啊,name要不要被外界知道,要,所以呢,定义在@interface当中:

Girl.h文件当中:

#import <Foundation/Foundation.h>
@interface Girl:NSObject
@property(nonatomic,strong)NSString *name;
@end

那么Girl是不还有个show方法啊,这个show方法,我需不需要被外界调用,需要,把好的一面,是不展示给别人呐,所以,show方法,定义在@interface当中:

Girl.h文件当中:

#import <Foundation/Foundation.h>

@interface Girl : NSObject
@property(nonatomic,strong)NSString *name;

  • (void)show;
    @end

Girl.m文件当中,实现一下就可以了:

#import “Girl.h”

@implementation Girl

  • (void)show
    {
    NSLog(@“show。。。”);
    }
    @end

但是,Girl还有个属性,年龄,首先,Girl是不有个年龄属性,是的,但是这个年龄属性,要不要给外界知道,不需要,那么年龄这个属性是不需要私有化,那我怎么私有,用什么啊,用延展,好,在Girl.m文件里面定义一个延展:

#import “Girl.h”
@interface Girl ()
@property(nonatomic,assign)int age;
@end
@implementation Girl

  • (void)show
    {
    NSLog(@“show。。。”);
    }
    @end

你看,这个时候,年龄就私有化了。

我们之前讲过,Girl是不还有个磨皮的方法,PS的方法,这个磨皮的方法,外界要知道不,是不只要自己知道就可以了吧,所以这个磨皮的方法是私有的,那么怎么私有化1个方法呢,把方法的声明写在延展当中,把实现写在本类的实现当中,就可以了:

在Girl.m文件中:

#import “Girl.h”
@interface Girl ()
@property(nonatomic,assign)int age;

  • (void)moPi;
    @end
    @implementation Girl
  • (void)show
    {
    NSLog(@“show。。。”);
    }
  • (void)moPi
    {
    NSLog(@“磨皮。。。”);
    }
    @end

我们在main.m文件中创建1个Girl对象:

在main.m文件中:

#import <Foundation/Foundation.h>
#import “Girl.h”
int main(int argc, const char * argv[])
{
Girl *g1 = [Girl new];
g1.name = @“rose”;//这个Girl对象展示给你的,只有名字
g1.age = //能拿到年龄吗,拿不到
[g1 show];//是不只有这个show方法啊,对外界
[g1 moPi];//有磨皮方法吗,没有

return 0;

}

总结:

这就是我们这个延展的应用场景,延展天生就是用来私有化类的成员的。

还有个经典应用啊,如下:一个ViewController就是一个界面,里面有一些控件,我不想让外界访问,就可以把它们声明在延展里面,它默认就给你留好了延展的位置了

猜你喜欢

转载自blog.csdn.net/madoca/article/details/126695733