前面讲过继承,由那篇文章往下接,下面我们熟悉一下super关键字
如果我们在子类中想要调用父类的被覆盖的方法,可以使用super关键来调用父类被覆盖的实例方法。继承中我们又一个fly的方法,就是鸟能飞翔的一个方法,如果在小鸡这个子类中用飞翔这个方法,可以
-(void)callOverridenMethod
{
//在类方法中通过super显示调用父类被覆盖的方法
[super fly];
}
通过上面这个方法,我们就可以让小鸡对象既可以调用自己重写的fly方法,也可以调用鸟对象被覆盖的fly方法(调用上方方法即可)。
super是OC提供的一个关键字,super用于限定该对象调用它从父类继承得到的属性 和方法。
正如self不能出现在类方法中一样,super也不能出现在类方法中。类方法调用只能是类本身,而不是对象。
当子类继承父类是,子类可以获得父类中定义的成员变量。但是,子类接口不允许定义于父类接口部分重名的成员变量。
下方示范错误的做法:
程序代码:LYXParent.h
#import <Foundation/Foundation.h>
@interface LYXParent : NSObject
{
@private
int _a;
}
@end
程序代码:LYXSub.m
#import "LYXParent.h"
@interface LYXSub : LYXParent
{
int _a;
}
@end
上方代码运行将会 出错。。提示重复。。
从上方可以看出,虽然父类中用@private限制了_a,但是在子类的接口部分依然不能定义与之重名的_a成员变量。
由此可见,不管父类接口部分的成员变量使用何种访问控制符限制,子类接口部分定义成员变量都不允许与父类接口部分定义的成员变量重名。
需要指出的是,在类实现部分的成员变量将会被限制在该类的内部,因此,父类在类实现部分定义的成员变量对子类没有任何影响。无论接口部分还是实现部分的成员变量,子类都完全可以与父类实现部分定义的成员变量一样的。反过来,子类在类实现部分定义的成员变量也不会受到父类接口部分的影响了。
当子类的实现部分定义了与父类重名的成员变量,子类成员变量就会隐藏父类的成员变量。此时,子类方法很难直接访问到父类的成员变量,此时可通过调用父类的方法来访问父类中被隐藏的成员变量。具体代码如下:
程序代码:LYXParent.h
#import <Foundation/Foundation.h>
@interface LYXParent : NSObject
@property(nonatomic,assign)int a;
@end
程序代码:LYXParent.m
#import "LYXParent.h"
@implementation LYXParent
@synthesize a = _a;
-(id)init
{
if (self = [super init]) {
self.a = 27;
}
return self;
}
@end
程序代码:LYXSub.h
#import "LYXParent.h"
@interface LYXSub : LYXParent
-(void)accessOwner;
@end
程序代码:LYXSub.m
#import "LYXSub.h"
@implementation LYXSub
{
//该成员变量将会隐藏父类的成员变量
int _a;
}
-(id)init
{
if (self = [super init]) {
self->_a = 7;
}
return self;
}
-(void)accessOwner
{
NSLog(@"子类中_a成员变量:%d",_a);
NSLog(@"父类中隐藏的_a成员变量:%d",super.a);
}
@end
程序代码:main.m
#import <Foundation/Foundation.h>
#import "LYXSub.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
LYXSub *sub = [[LYXSub alloc]init];
[sub accessOwner];
}
return 0;
}