黑马程序员 - OC语言 - 重写构造方法

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

有两个方法:
+alloc : (类方法)给对象分配空间的方法 -init:(对象方法)初始化对象的方法,<真正的构造方法>
有什么用?
在对象初始化的适合,就给属性赋值!
(如:当需要创建此类很多对象时,可以避免多行代码
Person *per1 = [Person new];
per1.age =10;
per1.name =@”huh”;

//构造方法只要一行代码 
Person *per1 = [[Person alloc]init]
)
场景1:在对象创建的一瞬间,就给对象赋值!
场景2: 在创建对象的时候,我想要动态的给对象赋值!
场景3: 让子类能够给自己的属性,初始化的时候能够赋值!
怎么用?
重写构造方法-(id) init
自定义构造方法-(id)initXXX
自定义子类的构造方法 -(id)initXXXX
Person *per3 = [[Person alloc] init];
用的时候注意什么?
1.NSObject的init方法必须调用
2.在没有特殊要求的情况下,子类和父类的赋值都应该在各自的类里面,各司其职,
 这样才能隔离父类的变化!

//  Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
//子类重写父类,声明不声明都可以
//-(id)init;
@property int age;
@end
//
//  Person.m
//
#import "Person.h"
@implementation Person
/*
 场景1:在对象创建的一瞬间,就给对象赋值!(对象创建的时候,必须调用init方法)
 子类重写父类的init方法,(init是真正的构造方法),
 在init方法里面,给属性赋值,就能实现初始化时,就给属性赋值的需求!
 -(id)init{
 _age = 10; //这还不够!
 }
 父类的init方法里面有很多的操作,我不知道!(如:我并不知道父类的init,是如何进行实力化得)
 因为子类重写父类的方法后,就不会在执行父类里面的操作,只会执行子类的方法了!
 可我想要的是,执行父类里面的操作 -- 创建对象!创建对象的同时,给属性赋值?
 【super init】 调用父类的init方法,self = 【super init】 用本身对象去接收!

 严谨:
    如果初始化失败,该怎么办?初始化失败会返回nil,就不需要对属性赋值! nil ==0;
    if (self != nil) {}

 注意:重写父类的方法,不需要声明也可以!
 */
-(id)init{
    if (self = [super init]) {//原理,非0则为真!
         _age =13;
    }

    return self;
}
@end
//
//  Cat.h
//
#import <Foundation/Foundation.h>
@interface Cat : NSObject
@property NSString *name;
@property int age;
-(id)initCat:(NSString*) name Age:(int)age;
@end
//
//  Cat.m
//
/*
 场景2:在创建对象的时候,我想要动态的给对象赋值!
    直接对重写父类的-(id)init方法,进行传参 ----不对,因为父类并没有带参数init方法!
    自定义带参数的init方法里面调用父类的init方法!

 注意:方法一定要声明,因为调用的是自己的方法,而不是父类的方法!
 */
#import "Cat.h"
@implementation Cat
-(id)initCat:(NSString*) name Age:(int)age{
    if(self = [super init]){
        _age = age;
        _name = name;
    }

    return self;
}
@end
//
//  BSCat.h
//
#import <Foundation/Foundation.h>
#import "Cat.h"
@interface BSCat : Cat
@property NSString *color;//颜色
-(id)initBSCat:(NSString *)name Age:(int)age Color:(NSString *)color;
@end
//
//  BSCat.m
//
#import "BSCat.h"
@implementation BSCat
/*
 场景3:让子类能够给自己的属性,初始化的时候就赋值!且继承父类的属性也能够动态赋值?
 分析:   首先它是个自定义的动态初始化
        -(id)initBSCat:(NSString *)name Age:(int)age Color:(NSString *)color
        可是,因为父类给属性,定义的是@property
        (@property自动生成的属性的默认是@private权限,只能在本类使用,不能在子类使用)
        所以,两种解决方案
          1) 手动更改父类的get和set方法!(缺陷,可扩展性差.如:父类要改个名字,子类也要跟着改)
             调用NSObject 的init方法
             if(self=[super init]){
             _name = name;//_name2 = name;
             _age =age;
             _color = color;
             }
          2) 调用父类Cat的initCat方法!(父类的修改,对子类没有影响.)

*/
-(id)initBSCat:(NSString *)name Age:(int)age Color:(NSString *)color{

    if(self =[super initCat:name Age:age]){//调用父类的方法
        _color = color;//添加自己的操作

    }
    return self;
}
@end
/*
    main.m
    构造方法
    是一个对象在初始化的时候执行的方法.
    init才是真的构造方法
    构造方法的操作有两种:
    1.重写.
    优点:实现简单. 不足:不能够根据不同对象赋不同的值,属性的值是固定的.
    2.自定义构造
    优点:使用灵活,可以根据不同的对象给属性设定不同的值. 不足:写法比较麻烦一些.
    3.子类继承父类自定义构造的写法.
    在子类里自定义构造时,要调用父类的自定义构造,而不是NSObject的init.这样才能隔离父类的变化.
    而且,父类的属性可以保持私有化private.
 */
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Cat.h"
#import "BSCat.h"
int main(int argc, const char * argv[]) {
    /*
     new 方法其实是封装了两个方法
     +alloc:给对象分配一块内存(类方法)
     -init:初始化这个对象(对象方法)
     */
//    Person *per = [Person new];

//    可以不初始化对象,直接赋值,但是不推荐,有时会出不可预知的错误
//    Person *per1 = [Person alloc];
//    per1.age =10;
//    NSLog(@"age1 =%d",per1.age);

//    标准方式
//    Person *per3 = [[Person alloc] init];
//    Person *per1 = [Person alloc];
//    Person *per2 = [per1 init];
//    per2.age =20;
//    NSLog(@"age2 =%d",per2.age);
//    简洁方式
    Person *per3 = [[Person alloc] init];
    per3.age =30;
    NSLog(@"age3 =%d",per3.age);
//    场景1:在对象创建的一瞬间,就给对象赋值!(对象创建的时候,必须调用init方法)
    Person *per4 = [[Person alloc]init];
    NSLog(@"age4 = %d",per4.age);


//    场景2:   在创建对象的时候,我想要动态的给对象赋值!
    Cat *ct = [[Cat alloc]initCat:@"boshimao" Age:3];
    NSLog(@"name = %@ ,age = %d",ct.name,ct.age);


//    场景3:让子类能够给自己的属性,初始化的时候就赋值!且继承父类的属性也能够动态赋值?
//    以下两个输出的结果是一样得,因为在BSCat实现里面,调用的就是父类的init方法!
//    Cat *ca =[[BSCat alloc] initBSCat:@"boSiMao" Age:2 Color:@"hua"];
//    NSLog(@"name=%@ ,age =%d, color%@",ca.name,ca.age,((BSCat *)ca).color);

    BSCat *bs =[[BSCat alloc] initBSCat:@"boSiMao" Age:2 Color:@"hua"];
    NSLog(@"name = %@ ,age =%d, color = %@",bs.name,bs.age,bs.color);
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值