標籤:構造方法 構造方法的重寫 自訂構造方法 構造方法的情境 super關鍵字
———————————————————————————————————————————
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;
}
———————————————————————————————————————————
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Objective-C 【構造方法(重寫、情境、自訂)、super】