黑马程序员 - OC语言 - 重写构造方法
2015-12-18 15:28
393 查看
——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.在没有特殊要求的情况下,子类和父类的赋值都应该在各自的类里面,各司其职,
这样才能隔离父类的变化!
有两个方法:
+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; } 4000 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; }
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- js判断客户端是iOS还是Android等移动终端的方法
- IOS开发环境windows化攻略
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解
- IOS 改变键盘颜色代码
- 举例详解iOS开发过程中的沙盒机制与文件
- Android和IOS的浏览器中检测是否安装某个客户端的方法
- 分享一个iOS下实现基本绘画板功能的简单方法
- javascript实现阻止iOS APP中的链接打开Safari浏览器