zoukankan      html  css  js  c++  java
  • Objective-C 【构造方法(重写、场景、自定义)、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 p2->_age = %d",p1->_age,p2->_age);
            NSLog(@"**************************************************");
            
            Student *s=[[Student alloc]init];
            NSLog(@"s->_age = %d s->_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;
    }


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

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    1015: [JSOI2008]星球大战starwar
    Tyvj P1813 [JSOI2008]海战训练
    1012: [JSOI2008]最大数maxnumber
    1430: 小猴打架
    1270: [BeijingWc2008]雷涛的小猫
    1202: [HNOI2005]狡猾的商人
    1059: [ZJOI2007]矩阵游戏
    3039: 玉蟾宫
    1303: [CQOI2009]中位数图
    1002: [FJOI2007]轮状病毒
  • 原文地址:https://www.cnblogs.com/wzy294250051/p/4787889.html
Copyright © 2011-2022 走看看