您的位置:首页 > 移动开发 > Objective-C

Objective-C 【构造方法(重写、场景、自定义)、super】

2015-08-26 22:25 579 查看
———————————————————————————————————————————

super关键字的使用

#import <Foundation/Foundation.h>

@interface Animal : NSObject

-(void)run;

-(void)eat;

//+(void)eat;

@end

@implementation Animal

-(void)run

{

NSLog(@"Animal run!");

}

-(void)eat

{

NSLog(@"-Animal eat!-");

}

//+(void)eat //经过验证,super是不能指代父类 类对象 的,也就不能通过super来调用父类的类方法。

//{

// NSLog(@"+Animal eat!+");

//}

@end

@interface Dog : Animal

-(void)run;

@end

@implementation Dog

-(void)run

{

NSLog(@"Dog run!");

// [super run];

// [super eat];

}

@end

@interface BigYellowDog : Dog

-(void)run;

@end

@implementation BigYellowDog

-(void)run

{

NSLog(@"BigYellowDog run!");

[super run];//调用了父类的run方法(此时BigYellowDog的父类是Dog,Dog的父类是Animal,Dog和Animal中都有run方法,此时优先调用Dog的run方法),super指代父类Dog的实例对象。

[super eat];//调用了父类的eat方法(此时Dog类中没有eat方法,而Animal类中有,那么就调用Animal中的eat方法),super指代Animal的实例对象,所以说super是可以指代 父类的父类 的实例对象的。

//★super指代的是父类的实例对象。这句话要明白,因为run和eat都是对象方法,显然需要有对象来调用。故super指代的正是父类的实例对象。

}

@end

int main(int argc, const char * argv[]) {

@autoreleasepool {

BigYellowDog *byd=[[BigYellowDog alloc] init];

[byd run];

}

return 0;

}

———————————————————————————————————————————

重写构造方法

#import <Foundation/Foundation.h>

@interface Person : NSObject

{

@public

int _age;

}

@end

@implementation Person

//重写init方法,这样的话调用的时候子类覆盖了父类的init方法,就达到了重写的目的

- (instancetype)init

{

self=[super init];//init是一个对象方法,返回值是instancetype类型(和id类型差不多)。这个地方要先将原父类的init方法调用一遍,也就是先用父类原有的init方法执行一遍。为什么还要这么做呢?那是因为父类在init的时候可能会初始化失败,也可能产生其他未知的初始化信息。为了不掩盖父类所做的事情,所以我们的原则是先让父类将原来要做的事情做完,然后做一个判断,如果父类init成功(即不为空),那么就开始执行重写的init方法

if(self)//如果初始化成功

{

_age=10;//将实例对象的_age属性设置为10

}

return self;//最后返回这个对象(self指代的就是方法的调用者,也就是实例对象自身)

}

@end

@interface Student : Person

{

@public

int _sno;

}

@end

@implementation Student

-(instancetype)init

{

// 如果不写 self=[super init]; 也就是不做父类的初始化,那么输出s->_age = 0 , s->_sno = 1 ,这是为什么呢?

// 显然Student是Person的子类,Person中我们重写了init方法,让实例对象初始化的_age属性值为10,而Student的init如果只写_sno=1,显然就覆盖掉了父类_age的初始化,那么就不会初始化_age属性,这样造成了初始化的部分遗失,所以说重写init构造方法时要遵守严格的程序:

// ①先执行父类的init

self=[super init];

// ②判断self是否初始化成功

if(self)

// ③初始化当前类的实例变量

{

_sno=1;

}

// ④return self; 返回实例对象

return self;

}

@end

int main(int argc, const char * argv[]) {

@autoreleasepool {

Person *p1=[Person new];

Person *p2=[[Person alloc] init];

NSLog(@"p1->_age = %d\np2->_age = %d",p1->_age,p2->_age);

NSLog(@"**************************************************");

Student *s=[[Student alloc]init];

NSLog(@"s->_age = %d\ns->_sno = %d",s->_age,s->_sno);

}

return 0;

}

———————————————————————————————————————————

重写构造方法的应用场景

#import <Foundation/Foundation.h>

@interface Soldier : NSObject

@property Gun* gun;

-(void)fire;

@end

@implementation Soldier

//为Soldier类重写init方法,目的是每创建一个Soldier实例对象,就默认这个对象拥有一把枪,所以枪这个属性需要在初始化的时候附上

-(instancetype)init

{

if(self=[super init])

{

Gun *gun=[[Gun alloc]init];

_gun=gun;

}

return self;

}

-(void)fire

{

[_gun shoot];

}

@end

@interface Gun : NSObject

@property int bulletCount;

-(void)shoot;

@end

@implementation Gun

//为Gun类重写init方法,目的是每创建一个Gun实例对象,就默认这个对象拥有3发子弹,所以子弹数目为3这个属性需要在初始化的时候附上

-(instancetype)init

{

if(self=[super init])

{

_bulletCount=3;

}

return self;

}

-(void)shoot

{

_bulletCount--;

NSLog(@"shoot!!!!!!剩余子弹:%d",_bulletCount);

}

@end

int main(int argc, const char * argv[]) {

@autoreleasepool {

for (int i=0; i<20; i++) {

Soldier *s=[[Soldier alloc]init];//创建了20个大兵,让他们一人一把专属的枪,然后每把枪都有三发子弹,然后射击三次

[s fire];

[s fire];

[s fire];

}

}

return 0;

}

———————————————————————————————————————————

自定义构造方法

//自定义构造方法:

//我们要以指定的值进行初始化,比如说,我们对学生这个类进行初始化,那么我们需要初始化学生的 姓名、年龄、学号 等。

//注意事项:

//①自定义构造方法是一个对象方法

//②返回值是 instancetype 类型(id)

//③方法名一定要以 initWithXXXXX 命名

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property NSString* name;

@property int age;

-(instancetype)initWithName:(NSString *)name andAge:(int)age;

@end

@implementation Person

-(instancetype)initWithName:(NSString *)name andAge:(int)age//我们的这些自定义的构造方法一定要在.h文件中声明

{

if (self=[super init]) {

_name=name;

_age=age;

}

return self;

}

@end

@interface Student : Person

@property int sno;

-(instancetype)initWithName:(NSString *)name andAge:(int)age andSno:(int)sno;

@end

@implementation Student

-(instancetype)initWithName:(NSString *)name andAge:(int)age andSno:(int)sno

{

if (self=[super initWithName:name andAge:age]) {

_sno=sno;

}

return self;

}

@end

int main(int argc, const char * argv[]) {

@autoreleasepool {

Student *s=[[Student alloc]initWithName:@"wang" andAge:18 andSno:1];

NSLog(@"name:%@,age:%d,sno:%d",s.name,s.age,s.sno);

}

return 0;

}

———————————————————————————————————————————
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: