《IOS_OC》继承、多态、初始化方法、便利构造器

一:继承

面向对象的三大特征:封装(函数的定义封装)、继承(子类继承父类的实例变量和方法)、多态(下面会介绍)

继承的特点如下:

1、继承父类所有的实例变量和方法
 2、继承具有单一性,只能继承于一个父类
 3、不能相互继承,你和我不可以互相继承(单向性)
 4、可以重写(overWrite)父类的方法
 5、特有的实例变量写在子类里面去声明
 6、继承具有传递性,子类不仅仅继承父类的实例变量和方法,还继承父类的父类的父类的~~~的实例变量和方法

(一:怎样使用?)如:Student类继承Person类,具有Person类的所有实例变量和方法,还具有自己特有的实例变量和方法。

@interface Person : NSObject
{
    NSString *_name;
    NSString *_sex;
    NSInteger _age;
}

在Student类里面再声明自己特有的实例变量

{
    //Student类特有的实例变量
    //学号
    NSInteger _number;
    //成绩
    CGFloat _score;
}
//再声明在父类里面没有的set和get方法
-(void)setNumber:(NSInteger)number;
-(NSInteger)number;
-(void)setScore:(CGFloat)score;
-(CGFloat)score;

在main.m文件里面,Student创建的对象可以任意调用父类的方法和实例变量
        Student *stu=[Student alloc];
        [stu initWithName:@"红红" Sex:@"女" Age:23 Number:12 Score:89];
        [stu sayHi];

(二:怎样重写方法?)如果子类想用父类的方法,但又要修改一下,则,无需在.h文件里面再次声明,只需要在Student.m文件里面修改就可以了,如下:

注意:父类方法重写,无需在子类的.h文件里面再声明了,只需要重写方法就可以了,一般调用方法,会先到到本类去找,再到父类去找,再到父类的父类去找

-(void)sayHi
{
    [super sayHi];//这里直接调用父类的方法,跟初始化方法一样,已经有的东西不再写一遍
    NSLog(@"学生的姓名是%@,在OC中考了%f分",_name,_score);//这是学生类的实例方法所特有的东西。
}

然后再次调用该方法sayHi就会输出学生特有的方法。


二:多态

(1)多个子类继承于同一个父类,或者子类的子类的子类都调用父类的父类的同一个方法,并都重写了父类的方法,变成具有自己特色的方法,则就实现了,不同对象调用同一个方法名会有不同的结果的现象,成为多态!

如:

[per sayHi];

结果: 您好,我是小花,我的性别是女的,年龄是12

[stu sayHi];
结果:您好,我是红红,我的性别是女,年龄是23
          学生的姓名是红红,在OC中考了89.000000分
[cStu sayHi];
结果:您好,我是猪八戒,我的性别是男,年龄是23
          学生的姓名是猪八戒,在OC中考了89.000000分
          学院是文学院,专业是语文
(2)多态的第二种现象:(不是很懂)

//多态的另一种表现,父类指针可以指向子类的对象
         [cStu fallInLoveWith:[stu name]];
        [cStu fallInLoveWith:[per name]];

通常来说,子类总是含有一些父类没有的成员变量,或者方法函数。而子类肯定含有父类所有的成员变量和方法函数。所以用父类指针指向子类时,没有问题,因为父类有的,子类都有,不会出现非法访问问题。
但是如果用子类指针指向父类的话,一旦访问子类特有的方法函数或者成员变量,就会出现非法,因为被子类指针指向的由父类创建的对象,根本没有要访问的那些内容,那些是子类特有的,只有用子类初始化对象时才会有。


三:初始化方法

初始化方法的作用:在继承父类的实例变量,不想又要重新定义初始化方法。如下:

//(1)、由于想要重写父类的初始化方法,则需要用到指定初始化方法、自定义初始化方法
//自定义初始化方法:
-(instancetype)initWithName:(NSString *)name Sex:(NSString *)sex Age:(NSInteger)age Number:(NSInteger)number Score:(CGFloat)score
{
    _number=number;
    _name=name;
    _sex=sex;
    _age=age;
    _score=score;
    return self;
}

//(2)、由于上面有一些东西已经写过,还是比较麻烦,于是又有下面的初始化方法
-(instancetype)initWithName:(NSString *)name Sex:(NSString *)sex Age:(NSInteger)age Number:(NSInteger)number Score:(CGFloat)score
{
    //super就是一个编译器指令,给super发消息会调用父类中相应的地方去
    self=[super initWithName:name Sex:sex Age:age];//这里直接调用父类的已经定义好的部分初始化
    //还不完整,还需要判断:self不能是空的值
    if (self !=nil) {
        _number=number;
        _score=score;
    }
    return self;
}


四:便利构造器

便利构造器的作用是:方便定义多个对象时,无需重复为每个对象申请分配空间和初始化,只要是属于同一个类的对象都可以用一句话创建。

步骤:

(1)在某一类的.h文件里面编写代码声明:

//便利构造器(+)开头的(因此是一个类方法),格式:+类名(小写开头)+实例变量+参数(包括父类的三个参数在内所有实例变量)
+(instancetype)studentWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age number:(NSInteger)number score:(CGFloat)score;

(2)在某一类的.m文件里面编写实现创建对象的方法过程:

便利构造器(+)开头的,格式:+类名(小写开头)+实例变量+参数
+(instancetype)studentWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age number:(NSInteger)number score:(CGFloat)score
{
    Student *stu=[[Student alloc] initWithName:name Sex:sex Age:age Number:number Score:score];
    return stu;
}

(3)在main.m文件里面使用便利构造器来创建多个上面所说的类的对象

      //创建Student的多个类

        Student *stu1=[Student studentWithName:@"张三" sex:@"男" age:23 number:12 score:89];
           Student *stu2=[Student studentWithName:@"李四" sex:@"男" age:23 number:45 score:68];

       //调用方法

       [stu1 sayHi];

       [stu2 sayHi];

五、self的作用

(1)在实例方法(-减号)里面,self表示返回的是一个调用本方法的对象的地址,验证如下:

-(instancetype)initWithName:(NSString *)name Sex:(NSString *)sex Age:(NSInteger)age
{
    //对继承于NSObject的实例变量进行初始化,默认情况下是有,self判断的
    self =[super init];
    if (self!=nil) {
        _name=name;
        _sex=sex;
        _age=age;
    }
    NSLog(@"实例方法中,self的地址是%p",self);//实例方法中self指当前调用该方法的对象的地址
    return self;//self是当前类的对象,调用本方法的对象,如果在+加号方法里面,则表示在类方法中,self表示当前类
}

结果返回的是:实例方法中,self的地址是0x10010e470

(2)在类方法(+加号方法里面)中self表示的是一个当前的类,如下验证:

//便利构造器,相当于把创建对象的alloc和init封装起来
+(instancetype)personWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age
{
    NSLog(@"在类方法中,self=%@",self);//结果打印的是“在类方法中,self=Person”说明表示在类方法中,self表示当前类
//需要返回值,则需要创建一个对象
    Person  *per=[[Person alloc]initWithName:name Sex:sex Age:age];
    return per;
}

结果输出:在类方法中,self=Person

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大小小丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值