对象初始化
[[class alloc] init] 中alloc负责为实例变量分配内存病将内存空间重置为0,init则初始化对象
多个自定义动态初始化方法:
#import "MyCar.h"
@implementation MyCar
@snythesize brand = _brand;
@snythesize model = _model;
@synthesize color = _coor;
//重写 init 初始化方法
- (void) init
{
//调用父类的 init 方法初始化对象病赋予self
//当 self 不为 nil 时,表示初始化成功,可继续
if(self = [super init])
{
self.brand = @"奥迪";
self.model = @"Q5";
self.color = @"黑色";
}
return self;
}
//自定义初始化方法
- (void) initWithBrand:(NSString*) brand model:(NSString*) model
{
if(self = [super init])
{
self.brand = brand;
self.model = model;
self.color = @"银色";
}
return self;
}
- (void) initWithBrand:(NSString*) brand model:(NSString*) model color:(NSString*) clolor
{
//用 initWithBrand: model: 初始化对象并赋予self,属于复用代码,更方便
if(self = [self initWithBrand: brand ,model:model])
{
//此处只赋值 color 即可
self.color = colour;
}
return self;
}
@end
类的继承
子类继承父类的格式:
@interface SubClass: SuperClass
{
//定义成员变量
}
//定义方法
@end
子类会继承父类的如下内容:
- 继承父类的全部成员变量,故而子类中不应该存在与父类同名的成员变量
- 继承父类的全部方法,包括初始化方法
接口部分:
#import <Foudation/Foundatioin.h>
@interface MyParent :NSObject
{
int (nonatomic, assign) _a;
}
@property (nonatomic, assign) int a;
@property int weight;
- (void) showWeight;
@end
@interface MySub: MyParent
- (void) accessOwner;
@end
实现部分:
#import <Foundation/Foundation.h>
#import "MyParent.h"
@plementation MyParent
@snythesize a = _a;
@snythesize weight;
- (id) init
{
if(self = [super init])
{
self->_a = 5;
}
return self;
}
- (void) showWeight
{
NSLog(@"weight is: %d", self.weight);
}
@end
@implementation MySub
{
//该成员变量会隐藏 MyParent 中的同名成员变量
int _a;
}
- (id) init //子类的 init 方法覆盖了父类的 init 方法
{
if(self = [super init])
{
self->_a = 7;
}
return self;
}
- (void) accessOwner
{
//直接访问当前变量的成员
NSLog(@"当前成员变量的值为:%d", _a);
//当问父类中被隐藏的成员变量
NSLog(@"父类中被隐藏的成员变量值为:%d", super.a);
}
@end
main()部分:
#import <Foundation/Foundatioin.h>
#import "MyParent.h"
int main()
{
@autoreleasepool
{
MySub* sub = [[MySub alloc] init];
[sub accessOwner]; //会依据方法显示子类与父类 a 的值
sub.weight = 75; //子类可以访问父类的属性
[sub showWeight]; //子类可以调用父类的方法
}
}
多态
多态性
实现部分:
//接口部分忽略,自行编写,MySub为MyBase的子类
#import <Foundation/Foundation.h>
#import "MyBase.h"
@implementation MyBase
- (void) base
{
NSLog(@"调用MyBase的base方法。");
}
- (void) test
{
NSLog(@"调用MyBase的test方法。");
}
@end
@implementation MySub
- (void) test
{
NSLog(@"调用MySub的test方法。");
}
- (void) sub
{
NSLog(@"调用MySub的sub方法。");
}
@end
main()部分:
#import <Foundation/Foundation.h>
#import "MyBase.h"
int main(int attic, char* argv[])
{
@autoreleasepool
{
//编译时类型与运行时类型不一样,多态发生
MyBase bc = [[MySub alloc] init];
//会调用父类的base方法
[bc base];
//对调用子类重写的test方法
[bc test];
//由于 bc 的变异类型为 MyBase ,MyBase 没有提供 sub 方法,所以编译出错
[bc sub];
//将任意类型的指针变量赋值给 id 类型变量
id dyna = bc;
[id sub]; //由于 id 类型变量可接受任意类型指针变量,并且id 类型变量可以调用该变量实际所指对象的方法,故而该行代码无错
}
}
将子类对象赋予父类指针变量,成为向上转型(upcasting),这种变量可调用的方法范围为父类的方法范围,但实际调用的方法确实子类的方法。
判断指针变量实际类型以及强制类型转换
判断变量实际类型用以下方法:
- -(BOOL) isKindOfClass:clazz 判断对象是否为clazz或其子类的实例
- -(BOOL) isSubclassOfClass:clazz 判断对象是否为clazz子类的实例
int main()
{
@autoreleasepool
{
//声明 MySub* sub
MySub* sub = [[MySub alloc] init];
//如果 sub 为 MyBase或其子类的实例为 true ,则执行 if 内语句
if([sub isKindOfClass: [MyBase class]])
{
//将 sub 强制转换成 MyBase* 类型并赋予 base
MyBase* base = (MyBase*) sub;
}
}
}