Objective-C 【構造方法(重寫、情境、自訂)、super】

來源:互聯網
上載者:User

標籤:構造方法   構造方法的重寫   自訂構造方法   構造方法的情境   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】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.