OC中的self和super
在上一节的学习中,可能大家对“_name”比较困惑,有一些疑问。这一节带领大家探索一下_name是怎么回事。
在上一节的学习中,我们在例如重写name属性的get方法中用到了_name:
-(NSString *)name{
return _name;
}
有朋友可能会注意到,为什么name前面会加一个“_”呢?“_name”是什么呢?
在了解_name之前,我们首先要了解一个关键字的使用:self。
在OC中,当我们创建一个类之后,其实我们就已经拥有了一个该类的对象,它的名字叫:self。它和我们创建的对象的区别在于self在创建本类时就产生了,在编程过程中用self进行类中属性和方法的实现。而在外部使用类的时候,我们就不能在使用self了,必须创建一个本类的对象(因为每个类都有一个self,OC不知道你指的是哪一个self)。
它在本类中起到非常重要的作用,例如:在本类一个方法中我们需要调用另一个方法,那就会产生一个问题,怎么在本类中调用本类中的方法呢?总不能类中声明一个本类的对象吧(不能这么干,例如有人这个类,而在这个类中却有“ZhangSan”这么一个人,还没有人类呢,就产生了ZhangSan这个人了,不符合逻辑)。
OC已经帮我们想到了这个问题的解决办法,就是采用self这个关键字。对于上面提到的问题,我们就可以采用[self 本类方法]来调用实现我们的目的。
对于本类中的方法调用是这样,对于本类中的属性同样是这样。例如我们要调用类中的name属性,我们就可以这样写:self.name。这么写我们就获取到了类中的name属性的值,我们可以对他进行操作:
self.name=@"zhang"
通过前面的学习,我们应该知道,本类对象.属性如果在等号左侧的话,就等于间接的调用该属性的set方法。self同样符合,它也会调用name属性的set方法。运行时,就如同:
[self setName:@”zhang”];
NSString * theName=self.name;
这是在调用那么属性的get方法。不再解释。
对于在本类中的属性调用,OC还提供了另外一种方式,当你采用方式三时,在声明这个属性的同时,还隐式生成了一个带有“_”的同名的属性_name,以方便程序员调用name属性。
而且使用_name还有另外一个好处,就是使用它调用这个属性的时候,不会调用这个属性的set或get方法。
可能你会问,既然它不会调用自己的get和set方法,用它干什么呢?有一个编程的地方就非它不可。
例如前面我们提到的,要对我们声明的属性进行重写它的get方法,返回值就必须使用_name。
如果使用self.name会出现什么情况呢?
我们前面讲过self.name会调用它的set方法或get方法。这样就会出现get方法中在调用get方法或者是set方法中在调用set方法,如此不断重复下去,造成死循环,程序将崩溃。
所以在这种地方,我们就只能使用_name的这种形式。
可能有朋友会产生疑惑,那究竟什么时候用_name,什么时候用self.name呢?
如果在编写过程中需要在类中调用本类的属性,如果这个地方必须调用get或set方法,那就必须使用self.name这种方式,如果在get或者set方法中,就必须使用_name的方式,如果不是上述的两种情况,使用哪个都可以。
扩展:
在OC面向对象大环境下,不但提供有本类的self,还有父类的super关键字。
super关键字和self关键字的使用是一样的,唯一不同的就是,self代表本类的一个对象,而super则代表父类的对象。
如果你想在本类中调用父类中的方法,那就采用[super 方法名]的方式。
在上一节的学习中,我们在例如重写name属性的get方法中用到了_name:
-(NSString *)name{
return _name;
}
有朋友可能会注意到,为什么name前面会加一个“_”呢?“_name”是什么呢?
在了解_name之前,我们首先要了解一个关键字的使用:self。
在OC中,当我们创建一个类之后,其实我们就已经拥有了一个该类的对象,它的名字叫:self。它和我们创建的对象的区别在于self在创建本类时就产生了,在编程过程中用self进行类中属性和方法的实现。而在外部使用类的时候,我们就不能在使用self了,必须创建一个本类的对象(因为每个类都有一个self,OC不知道你指的是哪一个self)。
它在本类中起到非常重要的作用,例如:在本类一个方法中我们需要调用另一个方法,那就会产生一个问题,怎么在本类中调用本类中的方法呢?总不能类中声明一个本类的对象吧(不能这么干,例如有人这个类,而在这个类中却有“ZhangSan”这么一个人,还没有人类呢,就产生了ZhangSan这个人了,不符合逻辑)。
OC已经帮我们想到了这个问题的解决办法,就是采用self这个关键字。对于上面提到的问题,我们就可以采用[self 本类方法]来调用实现我们的目的。
对于本类中的方法调用是这样,对于本类中的属性同样是这样。例如我们要调用类中的name属性,我们就可以这样写:self.name。这么写我们就获取到了类中的name属性的值,我们可以对他进行操作:
self.name=@"zhang"
通过前面的学习,我们应该知道,本类对象.属性如果在等号左侧的话,就等于间接的调用该属性的set方法。self同样符合,它也会调用name属性的set方法。运行时,就如同:
[self setName:@”zhang”];
NSString * theName=self.name;
这是在调用那么属性的get方法。不再解释。
对于在本类中的属性调用,OC还提供了另外一种方式,当你采用方式三时,在声明这个属性的同时,还隐式生成了一个带有“_”的同名的属性_name,以方便程序员调用name属性。
而且使用_name还有另外一个好处,就是使用它调用这个属性的时候,不会调用这个属性的set或get方法。
可能你会问,既然它不会调用自己的get和set方法,用它干什么呢?有一个编程的地方就非它不可。
例如前面我们提到的,要对我们声明的属性进行重写它的get方法,返回值就必须使用_name。
如果使用self.name会出现什么情况呢?
我们前面讲过self.name会调用它的set方法或get方法。这样就会出现get方法中在调用get方法或者是set方法中在调用set方法,如此不断重复下去,造成死循环,程序将崩溃。
所以在这种地方,我们就只能使用_name的这种形式。
可能有朋友会产生疑惑,那究竟什么时候用_name,什么时候用self.name呢?
如果在编写过程中需要在类中调用本类的属性,如果这个地方必须调用get或set方法,那就必须使用self.name这种方式,如果在get或者set方法中,就必须使用_name的方式,如果不是上述的两种情况,使用哪个都可以。
扩展:
在OC面向对象大环境下,不但提供有本类的self,还有父类的super关键字。
super关键字和self关键字的使用是一样的,唯一不同的就是,self代表本类的一个对象,而super则代表父类的对象。
如果你想在本类中调用父类中的方法,那就采用[super 方法名]的方式。