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

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. [置顶] 《Windows编程零基础》__2 一个完整的程序

    Windows开发的常识 1)窗口 Windows中最基本的概念也许就是窗口了,每一个前台程序都至少有一个窗口,一个窗口也是你可以看到的部分,比如,QQ有如下的登录窗口 基本上你在Windows中可见 ...

  2. 网络编程中常见地址结构与转换(IPv4/IPv6)

    1. sockaddr/sockaddr_in/in_addr (IPv4).sockaddr6_in/in6_addr/addrinfo (IPv6) struct sockaddr { unsig ...

  3. Java 中队列的使用

    刚才看见群里的一个朋友在问队列的使用,确实在现实的写代码中非常少使用队列的,反正我是从来没使用过.仅仅是学数据结构的时候学过. 以下是我写的一个小样例,希望有不足之处请提出改正.O(∩_∩)O~ 看代 ...

  4. 关于AS3的垃圾回收

    FlashPlayer运行GC(Gabage Collection)的时间并不固定,它会根据你的内存的占用情况来决定运行GC的时间.它会根据用户机器的内存值来设定一个阀值,然后将程序的占用内存量保存在 ...

  5. mysql索引常见问题

    一:对于先建索引再插入和先插入再统一建索引效率: 对于大数量的表来说, 先加载数据再来定义全文索引的 速度要远远优于在一个已经定义好全文索引的表里面插入大量数据的速度.一定会问:这是问什么呢?其实,道 ...

  6. Linux内核初始化定义

    转载:http://blog.csdn.net/beatbean/article/details/8448623 1. Compile宏控制 位于include/linux/init.h /* The ...

  7. Maven学习小结(五 pom.xml详解[转])

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  8. hibernate 创建session

    //1. 创建一个 SessionFactory 对象 SessionFactory sessionFactory = null; //1). 创建 Configuration 对象: 对应 hibe ...

  9. Adobe Edge Animate –EdgeCommons Log和全局变量设置功能

    Adobe Edge Animate –EdgeCommons Log和全局变量设置功能 版权声明: 本文版权属于 北京联友天下科技发展有限公司. 转载的时候请注明版权和原文地址. 一.Log功能 当 ...

  10. [改善Java代码]提防包装类型的null值

    建议26: 提防包装类型的null值 我们知道Java引入包装类型(Wrapper Types)是为了解决基本类型的实例化问题,以便让一个基本类型也能参与到面向对象的编程世界中.而在Java 5中泛型 ...