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

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】的更多相关文章

  1. 12_Java面向对象_第12天(构造方法、this、super)_讲义

    今日内容介绍 1.构造方法 2.this关键字 3.super关键字 4.综合案例 01构造方法引入 A:构造方法的引入 在开发中经常需要在创建对象的同时明确对象的属性值, 比如员工入职公司就要明确他 ...

  2. 构造方法,this,super,final,static

    1构造方法 一个Person类,属性都被private了,外界无法直接访问属性,必须对外提供相应的set和get方法.但如果需要在创建对象的同时明确对象的属性值,就需要构造方法了. 1.1定义 构建创 ...

  3. Java面向对象(构造方法、this、super)

    面向对象 今日内容介绍 u 构造方法 u this u super 第1章 构造方法 我们对封装已经有了基本的了解,接下来我们来看一个新的问题,依然以Person为例,由于Person中的属性都被pr ...

  4. 重写并自定义依赖的原生的Bean方法

    转载请注明出处: 在项目开发过程中,往往是直接应用很多jar包中依赖且声明好的Bean,拿来即用,但很多场景也需要对这些原生的Bean 进行自定义,定制化封装,这样在项目使用的过程中,可以使用自定义的 ...

  5. 4、构造方法、this、super

    构造方法 构造方法引入 * A:构造方法的引入 在开发中经常需要在创建对象的同时明确对象的属性值,比如员工入职公司就要明确他的姓名.年龄等属性信息. 那么,创建对象就要明确属性值,那怎么解决呢?也就是 ...

  6. Java之构造方法及this、super关键字

    有关构造方法的理解: 需要对对象的数据进行初始化,则创建一个构造方法,此方法名字和类名一样,但是没有返回值(类型和具体的值都没,但是可以写return;).构造方法是用来创建对象的,所以是不能被对象调 ...

  7. java基础(12):构造方法、this、super

    1. 构造方法 我们对封装已经有了基本的了解,接下来我们来看一个新的问题,依然以Person为例,由于Person中的属性都被private了,外界无法直接访问属性,必须对外提供相应的set和get方 ...

  8. 构造方法概念,自定义构造(init)方法的用途, 类工厂方法(就是直接用类名 类调用)

    一. 构造方法 构造方法:在OC中init开头的方法, 我们称之为构造方法 构造方法的用途: 用于初始化一个对象, 让某个对象一创建出来就拥有某些属性和值 // 比如我们定义一个Person的类,然后 ...

  9. JAVASE(九)面向对象特性之 : 继承性、方法重写、关键字super、

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.继承性 1.1 为什么要类的继承性?(继承性的好处) ①减少了代码的冗余,提高了代码的复用性:②更好 ...

  10. 为什么java的构造方法中this()或者super()要放在第一行

    java的构造方法中如果自己显性的调用super()的时候一定要放在第一行,如不是的话就会报错. 为什么一定要在第一行? super()在第一行的原因就是: 子类有可能访问了父类对象, 比如在构造函数 ...

随机推荐

  1. UVa572 Oil Deposits DFS求连通块

      技巧:遍历8个方向 ; dr <= ; dr++) ; dc <= ; dc++) || dc != ) dfs(r+dr, c+dc, id); 我的解法: #include< ...

  2. PostgreSQL的 initdb 源代码分析之九

    继续:下面的是定义信号处理函数. /* * now we are starting to do real work, trap signals so we can clean up */ /* som ...

  3. java递归简易应用教程

    package com.xiaohao.test; import java.util.ArrayList;import java.util.List;import java.util.Locale;i ...

  4. C++,C#,Python

    1.C++的思路:无论是基本类型,还是类类型,对象的传递提供了两种方式,一个是整体拷贝,一个是复制引用.整体拷贝对应着copy构造和copy赋值,复制引用就是通过引用或者指针实现的,当然指针本身还是整 ...

  5. SAP标准教材列表

    AC010 mySAP Financials Overview to Financial Accounting and ReportingAC020 mySAP Financials Investme ...

  6. Codeforces Gym 100342C Problem C. Painting Cottages 暴力

    Problem C. Painting CottagesTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/1 ...

  7. android拦截短信并屏蔽系统的Notification

    拦截短信有几个关键点: 1.android接收短信时是以广播的方式 2.程序只要在自己的Manifest.xml里加有"接收"SMS的权限 <uses-permission  ...

  8. 搭建Nginx图片服务器

    搭建Nginx图片服务器 Part-I 安装Nginx 安装PCRE 下载 ngx_cache_purge 并解压,用来清除缓存 下载Nginx并解压 cd nginx-1.7.7 编译,--pref ...

  9. [Jest] Track project code coverage with Jest

    Jest comes pre-packaged with the ability to track code coverage for the modules you're testing, but ...

  10. iOS与日期相关的操作

    // Do any additional setup after loading the view, typically from a nib. //得到当前的日期 注意week1是星期天 NSDat ...