Objective-C_继承、初始化方法、便利构造器
来源:互联网 发布:女士马丁靴品牌知乎 编辑:程序博客网 时间:2024/06/07 10:14
一、继承
继承的上层:父类,继承的下层:子类。继承是单向的,不能相互继承。继承具有传递性:A继承于B,B继承于C,A具有B和C的特征和⾏为。子类能继承父类全部的特征和行为。
示例
打僵尸。需求:
1、定义普通僵尸类:
实例变量:僵尸总血量、僵尸每次失血量。
方法:初始化方法(总血量)、被打击失血、死亡。
2、定义路障僵尸类:
实例变量:僵尸总血量、僵尸每次失血量,道具,弱点。
方法:初始化方法(总血量)、被打击失血、失去装备、死亡。
3、定义铁桶僵尸类:
实例变量:僵尸总血量、僵尸每次失血量,道具,弱点。
方法:初始化方法(总血量)、被打击失血、失去装备、死亡。
4、在main.m中创建普通僵尸对象,设置总血量50,每次失血量为 3,没有道具。
5、在main.m中创建路障僵尸对象,设置总血量80,每次失血量为 2,设置道具为路障。
6、在main.m中创建铁桶僵尸对象,设置总血量120,每次失血量为 1,设置道具为铁桶。
如果定义三个类:普通僵尸、路障僵尸、铁桶僵尸。它们会有很多重复的实例变量和方法,这不仅是体力活,而且也不科学。面向对象提供了继承语法,能⼤大简化代码。把公共的方法和实例变量写在父类里,子类只需要写⾃己独有的实例变量和方法即可。继承既能保证类的完整,又能简化代码。
继承实现
#import <Foundation/Foundation.h> /* 子类 */ /* 父类 */@interface OrdinaryZombie : NSObject@end
#import "OrdinaryZombie.h" /* 子类 */ /* 父类 */@interface RoadblockZombie : OrdinaryZombie@end
继承特点
Objective-C中只允许单继承。没有父类的类称为根类,Objective-C中的根类是NSObject(祖宗)。
继承的内容:所有实例变量和方法。如果子类不满意父类方法的实现,可以重写(overwrite)父类的方法。
继承树
继承中⽅法的执行
self、super
self和super是Objective-C语言中的关键字。
super是编译器指令,并非对象。
作用:给super发消息,可以执⾏父类中实现的方法。
子类可以重写父类的方法,即:子类既有⾃己的实现,⼜有父类继承下来的实现,如果想使用父类的实现,向super发送消息。
self作用:调用自身的方法和属性,始终代表调用方法的对象。
self和super使用的简单示例代码如下:
- (instancetype)initWithName:(NSString *)name sex:(NSString *)sex{ /* * 详细解释[super init] * 父类中定义的实例变量通过向super请求初始化方法来得到初始化 * 向super请求初始化方法的消息连接起了所有继承树上的对象 * 父类的变量会比子类的变量先得到初始化 * 例如: CollegeStudent对象在初始化时, 会依次对NSObject, Student, CollegeStudent进行初始化 * 关于初始化方法, 请查阅本博文下面内容 */ self = [super init]; if (self) { _name = name; _sex = sex; } return self;}
二、初始化方法
使用Objective-C创建对象分为两步:
- 内存分配(开辟空间):为新对象动态的分配一段内存地址。
- 初始化:为这段内存空间赋初始值。
初始化方法在对象的整个生命周期里只使用一次。初始化方法命名一般以init开头;初始化方法可以在对象创建的时候给实例变量赋初值;初始化方法的返回值只能是id(或instancetype)或本类对象,不能是void。一个类可以有多个初始化方法。
完整的初始化方法,示例代码如下:
- (instancetype)initWithName:(NSString *)name sex:(NSString *)sex{ // 给super发送init消息: 即执行父类中实现的init方法 self = [super init]; if (self) { // 初始化设置 _name = name; _sex = sex; } // 返回初始化完成的对象 return self;}
注意:
学习继承之前,类与类之间没有关联,因此初始化方法没有
self = [super init];
字样,从而为实例变量逐一赋值。学习继承之后,⽗类中声明了共有的实例变量。作为父类,应该有自己的初始化方法,为这些共有的实例变量赋初值。
子类定义了除父类中公共实例变量之外的实例变量。在⾃身的初始化方法中,优先向super发送init消息,初始化公共变量,初始化成功之后,再初始化⾃身特有变量,从而完成全部实例变量的初始化。
初始化过程
- 子类的初始化方法中,优先调⽤父类的初始化方法。
- ⽗类的初始化⽅法中再调用其父类的初始化方法,依次往上调用,直至NSObject类。
- 处于最上层的初始化完成之后,回到第二层的初始化方法中,完成第二层的初始化。第二层的初始化完成之后,回到第三层的初始化方法中,依次执⾏初始化方法,直到本类的初始化方法完成。
初始化⽅法的特征
初始化方法是 “-”号方法。
返回值类型是 id 或者 instancetype。
以init开头。
可以带0到多个参数。
内部实现:先执⾏super的初始化方法,再初始化⾃⾝变量,return self。
三、便利构造器
便利构造器在初始化方法的基础上进行了封装,即封装了对象的创建过程。便利构造器是“+”号方法,返回 本类型 的实例,方法名以类名开头。可以有0到多个参数。内部实现,封装了alloc和初始化方法。使⽤起来更加简洁。
便利构造器的实现
1.声明和实现便利构造器。
+ (instancetype)personWithName:(NSString *)name sex:(NSString *)sex;+ (instancetype)personWithName:(NSString *)name sex:(NSString *)sex{ Person *person = [[Person alloc] initWithName:name sex:sex]; return person;}
2.使⽤便利构造器创建对象。
Person *person = [Person personWithName:@"小红" sex:@"女"];
其实,便利构造器的便利不仅是代码量的减少,也是对内存操作的便利,如果用便利构造器创建了一个对象,则在使用完毕后不用去释放该对象,出了自动释放池后,对象被自动销毁,在自动释放池销毁之前,我们持有对象,不用理会什么时候释放该对象(这是Objective-C内存管理的内容,博主会在后续的博文中详细说明)。
附录
开篇示例“打僵尸”的代码实现
本例题利用继承实现,题目要求较为简单,请仔细阅读代码。
普通僵尸类 OrdinaryZombie.h 代码如下:
#import <Foundation/Foundation.h>@interface OrdinaryZombie : NSObject{@protected NSInteger _fullOfBlood; /* 总血量 */ NSInteger _lossOfBlood; /* 每次失血量 */ NSString *_equipment; /* 道具 */ NSString *_weakness; /* 弱点 */}/* 实例变量setter, getter方法 */- (void)setFullOfBlood:(NSInteger)fullOfBlood;- (NSInteger)fullOfBlood;- (void)setLossOfBlood:(NSInteger)lossOfBlood;- (NSInteger)lossOfBlood;- (void)setEquipment:(NSString *)equipment;- (NSString *)equipment;- (void)setWeakness:(NSString *)weakness;- (NSString *)weakness;/* 初始化方法(总血量) */- (id)initWithBlood:(NSInteger)fullOfBlood;/* 被打击失血 */- (void)attacked;/* 死亡 */- (void)death;/* 失去装备 */- (void)loseEquipment;@end
普通僵尸类 OrdinaryZombie.m 代码如下:
#import "OrdinaryZombie.h"@implementation OrdinaryZombie- (void)setFullOfBlood:(NSInteger)fullOfBlood{ _fullOfBlood = fullOfBlood;}- (NSInteger)fullOfBlood{ return _fullOfBlood;}- (void)setLossOfBlood:(NSInteger)lossOfBlood{ _lossOfBlood = lossOfBlood;}- (NSInteger)lossOfBlood{ return _lossOfBlood;}- (void)setEquipment:(NSString *)equipment{ _equipment = equipment;}- (NSString *)equipment{ return _equipment;}- (void)setWeakness:(NSString *)weakness{ _weakness = weakness;}- (NSString *)weakness{ return _weakness;}- (id)initWithBlood:(NSInteger)fullOfBlood{ _fullOfBlood = fullOfBlood; return self;}- (void)attacked{ _fullOfBlood -= _lossOfBlood; if (_fullOfBlood <= 0) { _fullOfBlood = 0; } NSLog(@"剩余血量: %ld", _fullOfBlood);}- (void)death{ NSLog(@"普通僵尸, 死亡");}- (void)loseEquipment{ NSLog(@"失去装备");}@end
路障僵尸类 RoadblockZombie.h 代码如下:
#import "OrdinaryZombie.h"@interface RoadblockZombie : OrdinaryZombie@end
路障僵尸类 RoadblockZombie.m 代码如下:
#import "RoadblockZombie.h"@implementation RoadblockZombie- (void)death{ NSLog(@"路障僵尸, 死亡");}- (void)loseEquipment{ NSLog(@"路障僵尸"); [super loseEquipment];}@end
铁桶僵尸类 MetalBucketZombie.h 代码如下:
#import "OrdinaryZombie.h"@interface MetalBucketZombie : OrdinaryZombie@end
铁桶僵尸类 MetalBucketZombie.m 代码如下:
#import "MetalBucketZombie.h"@implementation MetalBucketZombie- (void)death{ NSLog(@"铁桶僵尸, 死亡");}- (void)loseEquipment{ NSLog(@"铁桶僵尸"); [super loseEquipment];}@end
main.m 代码如下:
#import <Foundation/Foundation.h>#import "OrdinaryZombie.h"#import "RoadblockZombie.h"#import "MetalBucketZombie.h"int main(int argc, const char * argv[]) { @autoreleasepool { /* 普通僵尸 */ OrdinaryZombie *ordZom = [[OrdinaryZombie alloc] initWithBlood:50]; /* 每次失血量 */ [ordZom setLossOfBlood:3]; while (1) { if ([ordZom fullOfBlood] == 0) { [ordZom death]; break; } [ordZom attacked]; } /* 路障僵尸 */ RoadblockZombie *roadZom = [[RoadblockZombie alloc] initWithBlood:80]; /* 每次失血量 */ [roadZom setLossOfBlood:2]; /* 装备类型 */ [roadZom setEquipment:@"路障"]; while (1) { /* 如果剩余50滴血 */ if ([roadZom fullOfBlood] <= 50) { /* 失去装备 */ [roadZom loseEquipment]; /* 失血量设置成普通僵尸 */ [roadZom setLossOfBlood:[ordZom lossOfBlood]]; break; } [roadZom attacked]; } while (1) { if ([roadZom fullOfBlood] == 0) { [roadZom death]; break; } [roadZom attacked]; } /* 铁桶僵尸 */ MetalBucketZombie *metalZom = [[MetalBucketZombie alloc] initWithBlood:120]; /* 每次失血量 */ [metalZom setLossOfBlood:1]; /* 装备类型 */ [metalZom setEquipment:@"铁桶"]; while (1) { /* 如果剩余50滴血 */ if ([metalZom fullOfBlood] <= 50) { /* 失去装备 */ [metalZom loseEquipment]; /* 失血量变成普通僵尸 */ [metalZom setLossOfBlood:[ordZom lossOfBlood]]; break; } [metalZom attacked]; } while (1) { if ([metalZom fullOfBlood] == 0) { [metalZom death]; break; } [metalZom attacked]; } } return 0;}
- Objective-C_继承、初始化方法、便利构造器
- 【继承】指定初始化方法【便利构造器】
- 03 继承 初始化方法 便利构造器
- 继承 初始化方法 便利构造器
- OCday3 初始化方法, 便利构造器, 继承
- OC_继承,便利构造器,初始化方法
- OC_继承,便利构造器,初始化方法
- OC_继承,便利构造器,初始化方法
- OC_继承,便利构造器,初始化方法
- OC_继承,便利构造器,初始化方法
- day3: 继承、初始化方法、便利构造器
- 继承 初始化方法 便利构造器
- [TwistedFate]继承 初始化方法 便利构造器
- 继承、初始化方法、便利构造器
- Objective-C_继承_初始化方法
- OC之继承,初始化方法,便利构造器
- OC_03_初始化方法_便利构造器_继承
- OC基础:继承.初始化方法,便利构造器
- scala隐式转换 及并发
- 深入浅出Tabhost+简单入门Demo
- Docker学习5 - 镜像
- 通过 VMware 安装 Mac OS X 10.10 Yosemite 8
- [poj 2960]S-Nim
- Objective-C_继承、初始化方法、便利构造器
- php中如何防止CSRF攻击
- DesignPattern之Mediator
- 编写struts.xml时的提示问题
- 【C#】:浅谈反射机制
- TI FAE 中文论坛
- 多线程下载服务端图片资源
- HDU_4547_CD操作(LCA+tarjan)
- Public Sale HDOJ